我有一个pandas数据帧,如下所示。如何删除任何剩余列的子集中的任何列?我想在不使用fillna的情况下这样做。
df = pd.DataFrame([ [1,1,3,3], [np.NaN,2,np.NaN,4]], columns=['A','B','C','D'] )
df
A B C D
0 1.0 1 3.0 3
1 NaN 2 NaN 4
我可以在这里确定A列是B的子集,C列是D的子集,如下所示:
if all(df[A][df[A].notnull()].isin(df[B]))
我可以在所有列上运行循环并删除子集列。但有没有更有效的方法来实现这一点,所以我有以下结果:
df
B D
0 1 3
1 2 4
感谢。
答案 0 :(得分:0)
它仍然需要迭代,但您可以使用此列表理解(使用类似于您提供的if语句)来保留列:
keep_cols = [x for x in df if not any(df.drop(x, axis=1).apply(lambda y: df[x].dropna().isin(y).all()))]
# ['B', 'D']
然后将结果与filter
:
df.filter(items=keep_cols)
# B D
# 0 1 3
# 1 2 4
这应该足够快,因为它仍然在其核心使用apply
,并且似乎比在循环中删除列更安全/更有效。
如果您热衷于单行解决方案,当然将列表分配给变量是可选步骤:
df.filter(items=[x for x in df if not any(df.drop(x, axis=1).apply(lambda y: df[x].dropna().isin(y).all()))])