确定一组值是否跨列出现一次,那么这些列中的一个值就不会再出现在 df 中

问题描述 投票:0回答:2

我有一个像这样的数据框:

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”是否显示,而与单位无关。我认为这个方法行不通。

我也探索了这个问题/答案,但这也不完全是我想要的。

python pandas series
2个回答
0
投票

这应该可以做到:

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)

0
投票

简单使用:

df['FAIL'] = (df['NUMERIC'].gt(50)
              & df['UNIT'].eq('psig')
              & ~df['ID'].duplicated(keep=False)
             )
© www.soinside.com 2019 - 2024. All rights reserved.