我有一个如下所示的数据框
Prop_ID Unit_ID Prop_Usage Unit_Usage
1 1 Res Res
1 2 Res Com
1 3 Res Ind
1 4 Res Res
2 1 Com Res
2 2 Com Com
2 3 Com Com
3 1 Ind Ind
3 2 Ind Com
4 1 Res - Com Res
4 2 Res - Com Com
4 3 Res - Com Ind
5 1 Com - Res Res
5 2 Com - Res Com
5 3 Com - Res Ind
5 4 Com - Res Com
从上面可以明显看出,一个属性可能具有多个1个单位。这意味着单位是属性的子类别。
从以上数据中,我想过滤Prop_Usage与Unit_Usage不匹配的行。在Prop_Usage列中有一个类别,即Res-Com,然后是Unit_Usage,则单位用法可以是Res或Com。
预期输出:
Prop_ID Unit_ID Prop_Usage Unit_Usage
1 2 Res Com
1 3 Res Ind
2 1 Com Res
3 2 Ind Com
4 3 Res - Com Ind
5 3 Com - Res Ind
答案 0 :(得分:1)
如果您的数据帧足够小,那么性能就不成问题了:
mask = df[['Prop_Usage', 'Unit_Usage']] \
.assign(
Prop_Usage=lambda x: x['Prop_Usage'].str.split(' - ').apply(set),
Selected=lambda x: ~x.apply(lambda row: row['Unit_Usage'] in row['Prop_Usage'], axis=1)
)
df.loc[mask['Selected']]
它的作用:
Prop_Usage
和Unit_Usage
复制到新的数据框中Prop_Usage
列替换为其本身的拆分版本。 “之后”版本中的每一行都是一组单位例如:
Prop_Usage Prop_Usage
(before) (after)
---------- ----------
Res {Res}
Res - Com --> {Res, Com}
Com - Res - Com {Com, Res}
Unit_Usage
是否在集合中。如果不是,请标记Selected = True
Selected
为True的原始数据框请注意,由于它使用.apply(..., axis=1)
,因此对于较大的数据帧,性能将不会很好。
答案 1 :(得分:-1)
熊猫可以直接将列与行进行比较:
df[~df.apply(lambda x: x.Unit_Usage in x.Prop_Usage, axis=1)]
应用lambda函数将比较每行中的字符串,并查看该行的Prop_Usage中Unit_usage中的内容是否存在,并产生布尔序列。您可以使用此布尔系列对数据框进行切片。