如果列的子集中的所有值等于0或N(取决于列),我有几个数据集需要放弃观察值。例如:当所有的值都等于多个条件时,在Pandas中放置观察值
df = pd.DataFrame({'one':[0,0,1,2,0], 'two':[0,0,0,0,0], 'three':['N','Y','N','Y','N']})
drop_subset = ['one', 'three']
In [4]: df
Out[4]:
one three two
0 0 N 0
1 0 Y 0
2 1 N 0
3 2 Y 0
4 0 N 0
我需要看的只是列one
和three
,然后删除行0和4只。如果它只是一个单一的值,而不是两个或更多的,我会用这样的:
df[~(df[drop_subset] == 0).all(axis=1)]
而且它会正常工作。但是,当我试图扩大它:
df[~(df[drop_subset] == 0 or df[drop_subset] == 'N').all(axis=1)]
我得到了可怕的:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(),a.item(), a.any() or a.all().
我原本以为对待每一个的使用any
或all
运营商内部条件......除了逻辑不会这样工作。我不需要知道任何或所有的值是否为0,或者分开确定是否有任何或所有的值都是N.我需要知道的所有的值是N还是0.也就是说,我可以这样做:
In [71]: (df[drop_subset] == 0)
Out[71]:
one three
0 True False
1 True False
2 False False
3 False False
4 True False
不为“N”的值也同时测试。虽然在这个小数据帧上我可以单独测试列one
0和列three
'N',但实际上我的drop_subset
包括几乎100个列,这三列在三个不同的数据集中是不同的,并且没有手动编码所有的列不知道哪些列会有0,哪些会有'N'。 我所知道的一切是,如果观察有所有 0或'N'跨该子集,那么我需要删除它。
我最后的手段是使用apply lambda,但由于数据的大小会很痛苦。另外,我觉得必须有一种矢量化的方式来表达Panadas中的这种逻辑,这就是我正在寻找的。
就是这样,谢谢。虽然我不得不说这是令人失望的,但这不能用布尔运算符来完成。 – Jeff
@JeffL。,可能有一些NumPy解决方案用于这种比较... – MaxU
那么,你对'isin'的建议是非常干净和快速的,所以没有真正的需要。它看起来像*应该*在Pandas中工作,这并不是真正的问题。 – Jeff