我们说我有以下数据框,我想选择任何一行的值等于列表中的任何项目:CodesOfInterest=['A','D']
>>> import pandas as pd
>>> d1=pd.DataFrame([['A','B','C','D'],['D','Q','S', np.nan],['R',np.nan,np.nan,np.nan],[np.nan,'A',np.nan,np.nan]],columns=['Code1','Code2','Code3','Code4'])
>>> d1
Code1 Code2 Code3 Code4
0 A B C D
1 D Q S NaN
2 R NaN NaN NaN
3 NaN A NaN NaN
>>>
这可以通过一行代码轻松完成:
>>> CodesOfInterest=['A','D']
>>> d1[(d1.isin(CodesOfInterest)==True).any(1)]
Code1 Code2 Code3 Code4
0 A B C D
1 D Q S NaN
3 NaN A NaN NaN
>>>
但是,我说以下第二个数据帧的索引与为该子集添加条件的第一个数据帧的索引相同。
>>> d2=pd.DataFrame([[1,0,1,0],[0,1,1, np.nan],[1,np.nan,np.nan,np.nan],[np.nan,1,np.nan,np.nan]],columns=['CodeStatus1','CodeStatus2','CodeStatus3','CodeStatus4'])
>>> d2
CodeStatus1 CodeStatus2 CodeStatus3 CodeStatus4
0 1 0 1 0
1 0 1 1 NaN
2 1 NaN NaN NaN
3 NaN 1 NaN NaN
>>>
现在我只想从我的d1中选择任何值与我的列表中的任何时间相等的行并且具有相应的' CodeStatus' (来自d2)等于1.并且相应的CodeStatus是指(Code1,CodeStatus1),(Code2,CodeStatus2)等对。
我有一种笨重的方法,需要循环遍历4个代码和代码状态中的每一个。见下文:
>>> bs=[]
>>> for Num in range(1,5):
... Code='Code'+str(Num)
... CodeStatus='CodeStatus'+str(Num)
... b=(df[Code].isin(CodesOfInterest))&(df[CodeStatus]==1)
... bs.append(b)
...
>>> Matches=pd.concat(bs,1)
>>>
>>> d1[(Matches==True).any(1)]
Code1 Code2 Code3 Code4
0 A B C D
3 NaN A NaN NaN
>>>
如您所见,记录1现在从数据框中删除,因为虽然它有一个包含代码' D'的列,但此代码的代码状态不等于1.
有没有更优雅的方法来使这个查询不需要循环遍历每一列?
答案 0 :(得分:1)
你可以这样做:
d1[pd.DataFrame((d1.isin(CodesOfInterest)==True).values*(d2==1).values).any(1)]