我有一个像这样的数据框:
DATE|ID|NUMERIC|UNIT
2021-01-01|1|55|psig
2019-01-01|1|20|psig
2018-01-01|2|55|psig
2017-01-01|3|40|psig
2016-01-01|4|55|cfpd
我有兴趣确定一行是否满足“NUMERIC”和“UNIT”列的条件,如果满足,该“ID”是否稍后不会出现在数据框中。 “日期”字段按降序排序以确定“稍后”。
条件是
df['NUMERIC']>50 & df['UNIT']=='psig'
如果“ID”满足这些条件并且“ID”不再出现,则它应该为布尔值 True。
如果满足或不满足条件并稍后出现在 df 中,则应为 False。我希望这个布尔值被捕获在名为“FAIL”的列中。
使用示例 df,我希望生成的 df 看起来像:
DATE|ID|NUMERIC|UNIT|FAIL
2021-01-01|1|55|psig|False
2019-01-01|1|20|psig|False
2018-01-01|2|55|psig|True
2017-01-01|3|40|psig|False
2016-01-01|4|55|cfpd|False
对于上下文,此 df 显示随时间的检查情况,如果检查结果 >50 psig,则失败,但前提是不再检查(无后续)
我能够通过以下方式确定“ID”是否在连续实例中满足这些条件:
df1 = df.copy()
df1 = df.loc[df['UNIT'] == 'psig']
c1 = df1['NUMERIC'].gt(50) & df1.groupby('ID')['NUMERIC'].shift(-1).gt(50)
c2 = df1['NUMERIC'].gt(50) & df1.groupby('ID')['NUMERIC'].shift().gt(50)
df1 = integ_psig[c1 | c2]
df1['FAIL'] = 'True'
对于这种新情况,我无法仅筛选“UNIT”为“psig”的行,因为我需要查看“ID”是否显示,而与单位无关。我认为这个方法行不通。
我也探索了这个问题/答案,但这也不完全是我想要的。
这应该可以做到:
df["CONDITION"] = (df['NUMERIC'] > 50) & (df['UNIT'] == 'psig')
df["ROW_CNT"] = df.groupby("ID")["DATE"].transform("count")
df["FAIL"] = (df["CONDITION"]) & (df["ROW_CNT"] ==1)
df.drop(labels=["CONDITION", "ROW_CNT"], axis=1, inplace=True)
简单使用:
df['FAIL'] = (df['NUMERIC'].gt(50)
& df['UNIT'].eq('psig')
& ~df['ID'].duplicated(keep=False)
)