尝试获取某些列的零列,而另一些列的零列。
import pandas as pd
import numpy as np
df=pd.DataFrame({'t':[0,0,0,np.nan],'t2':[0,0,2,3],'t3':[1,0,0,np.nan],'t4':[0,np.nan,2,3]})
zero=['t','t3']
nozero=['t2','t4']
数据框:
t t2 t3 t4
0 0.0 0 1.0 0.0
1 0.0 0 0.0 NaN
2 0.0 2 0.0 2.0
3 NaN 3 NaN 3.0
我尝试过:
df[((df[zero]==0).any(axis=1))&((df[nozero]!=0).any(axis=1))]
给出
t t2 t3 t4
1 0.0 0 0.0 NaN
2 0.0 2 0.0 2.0
也尝试过:
df[((df[zero]==0)&(df[nozero]!=0)).any(axis=1)]
给出一个空的数据框。
预期:
t t2 t3 t4
2 0.0 2 0.0 2.0
任何帮助都会很棒。谢谢。
编辑说明:
对于每对(t,t2和t3,t4),我都需要两个条件(ALL)都为真(零== 0和nozero!= 0),但是如果该行中的任何一对都为真,我希望行。
例如,来自以下数据框:
df = pd.DataFrame({'t': [0, 0, 11,0], 't2': [0, 0, 0, 0], 'z3': [0, 0, 12, 0], 't4': [0, 0, 2, 0],
't5': [0, 0, 0, 0], 'z6': [0, 0, 4, 0], 't7': [1, 1, 0, 1], 't8': [1, 1, 0, 1],
'z9': [1, 1, 0, 1], 't10': [1, 1, 0, 1], 't11': [1, 1, 0, 1], 'z12': [1, 1, 0, 1]})
nozero=['z3','z6','z9','z12']
zero=list(set(df.columns)-set(nozero))
t t2 z3 t4 t5 z6 t7 t8 z9 t10 t11 z12
0 0 0 0 0 0 0 1 1 1 1 1 1
1 0 0 0 0 0 0 1 1 1 1 1 1
2 11 0 12 2 0 4 0 0 0 0 0 0
3 0 0 0 0 0 0 1 1 1 1 1 1
我只想要第2行,因为any(t,t2)为零而z3不为零。
编辑说明:
以下代码生成我要保留的行(索引= 2)。有没有比.any或.all更为有效的方法? (因为这需要追加行,分配内存,循环等)
import pandas as pd
df = pd.DataFrame({'t': [0, 0, 11,0], 't2': [0, 0, 0, 0], 'z3': [0, 0, 12, 0], 't4': [0, 0, 2, 0],
't5': [0, 0, 0, 0], 'z6': [0, 0, 4, 0], 't7': [1, 1, 0, 1], 't8': [1, 1, 0, 1],
'z9': [1, 1, 0, 1], 't10': [1, 1, 0, 1], 't11': [1, 1, 0, 1], 'z12': [1, 1, 0, 1]})
nozero=['z3','z6','z9','z12']
zero1=['t','t4','t7','t10']
zero2=['t2','t5','t8','t11']
for x,y,z in zip(zero1, zero2, nozero):
print(df[((df[x]==0) | (df[y]==0)) & (df[z]!=0)])
答案 0 :(得分:0)
我认为是因为NaN。 NaN != 0 is True
df[((df[zero]==0).any(axis=1))&((df[nozero]!=0).any(axis=1))].dropna()
df[((df[zero]==0).any(axis=1))&((df[nozero]!=0).any(axis=1))&(df[zero+nozero].notnull().all(axis=1))]
t t2 t3 t4
2 0.0 2 0.0 2
df
t t10 t11 t2 t4 t5 t7 t8 z12 z3 z6 z9
0 0 1 1 0 0 0 1 1 1 0 0 1
1 0 0 0 0 0 0 0 0 1 12 4 1
2 11 1 0 0 2 0 1 0 0 0 0 0
3 0 1 1 0 0 0 1 1 1 0 0 1
df[((df[zero]==0).all(1))&((df[nozero]!=0).all(1))&(df[zero+nozero].notnull().all(1))]
t t10 t11 t2 t4 t5 t7 t8 z12 z3 z6 z9
1 0 0 0 0 0 0 0 0 1 12 4 1
答案 1 :(得分:0)
根据与@coldspeed的讨论,看来您正在使用看起来更像的数据框
t t2 t3 t4
0 0.0 0.0 1.0 0.0
1 0.0 0.0 0.0 NaN
2 0.0 2.0 0.0 2.0
3 NaN 3.0 NaN 3.0
4 0.0 1.0 0.0 0.0
在转换了建议的@coldspeed之类的数据类型之后,您可以继续并使用它来选择所需的数据。
In [193]: df[((df[zero] == 0).all(1) & (df[nozero] != 0).any(1))]
Out[193]:
t t2 t3 t4
1 0.0 0.0 0.0 NaN
2 0.0 2.0 0.0 2.0
4 0.0 1.0 0.0 0.0
第一个条件(df[zero]==0).all(1)
在zero
列中找到所有0
的值(all(1)
告诉熊猫按列减少)。第二个条件是在nozero
列中找到任何不为零的值,正如@Ananay所说,其中包括NaN
。
就像@Ananay在回答中说的那样,您可以使用NaN
删除具有dropna()
值的行,这样最终结果就是
In [194]: df[((df[zero] == 0).all(1) & (df[nozero] != 0).any(1))].dropna()
Out[194]:
t t2 t3 t4
2 0.0 2.0 0.0 2.0
4 0.0 1.0 0.0 0.0
我还建议您阅读有关.any()
和.all()
方法的更多信息。
编辑
我可以做到
df[((df['t']==0) | (df['t2']==0)) & (df['z3']!=0)]
但我不知道您是否要具体说明。问题只是为我以前的方法找到正确的布尔条件。我们希望第3行返回True,其他行返回False。您可以尝试将此问题重命名为“布尔索引以根据列列表的条件查找值”或进行搜索。
答案 2 :(得分:0)
由于我无法使用.any或.all获得所需的行,因此我编写了一种变通方法代码。如果您发现任何更有效的方法而无需遍历各列,请告诉我。感谢所有帮助@Ananay Mital,@ m42op64,@ coldspeed。
import pandas as pd
df = pd.DataFrame({'t': [0, 0, 11,0], 't2': [0, 0, 0, 0], 'z3': [0, 0, 12, 0], 't4': [0, 0, 2, 0],
't5': [0, 0, 0, 0], 'z6': [0, 0, 4, 0], 't7': [1, 1, 0, 1], 't8': [1, 1, 0, 1],
'z9': [1, 1, 0, 1], 't10': [1, 1, 0, 1], 't11': [1, 1, 0, 1], 'z12': [1, 1, 0, 1]})
nozero=['z3','z6','z9','z12']
zero1=['t','t4','t7','t10']
zero2=['t2','t5','t8','t11']
indices=set()
for x,y,z in zip(zero1, zero2, nozero):
i=df[((df[x]==0) | (df[y]==0)) & (df[z]!=0)].index.values
indices.update(i)
print(df.loc[list(indices)])
输出
t t2 z3 t4 t5 z6 t7 t8 z9 t10 t11 z12
2 11 0 12 2 0 4 0 0 0 0 0 0