替代遍历熊猫数据框行以应用条件?

时间:2020-07-23 15:30:17

标签: python pandas numpy

我有一个要根据某些条件修改的数据框。实际的数据框(下面的示例中有35k行,400列)比下面的示例大得多,并且有更多的患者列。

如果给定行的患者列下有2个NaN,我想删除整行。接下来,我想在数据框后面添加一列,其中包含每行所有患者值的df.std()。我读到不建议在pandas数据帧中进行迭代,但为此目的,我很难使用numpy。

输入:

In [1]: df=pd.DataFrame({'chromosome':[1,1,5,4], 
   ...:                  'strand':['-','-','+','-'], 
   ...:                  'elementloc':[4991, 8870, 2703, 9674], 
   ...:                  'Patient1_Psi': ['NaN', 0.25,0.63,0.92], 
   ...:                  'Patient2_Psi':[0.11, 0.45, 'NaN', 1.0], 
   ...:                  'Patient3_Psi':['NaN', 0.1, 'NaN', 0.4]}) 
   ...: df  

                                                                

Out[2]: 
   chromosome strand  elementloc Patient1_Psi Patient2_Psi Patient3_Psi
0           1      -        4991          NaN         0.11          NaN
1           1      -        8870         0.25         0.45          0.1
2           5      +        2703         0.63          NaN          NaN
3           4      -        9674         0.92            1          0.4

我想要的输出:

In [3]: df_new=pd.DataFrame({'chromosome':[1,4], 
   ...:                  'strand':['-','-'], 
   ...:                  'elementloc':[ 8870, 9674], 
   ...:                  'Patient1_Psi': [0.25,0.92], 
   ...:                  'Patient2_Psi':[0.45, 1.0], 
   ...:                  'Patient3_Psi':[0.1, 0.4], 
   ...:                   'std':[0.175594, 0.325781]}) 
   ...: df_new                                                                 


Out[4]: 
   chromosome strand  elementloc  Patient1_Psi  Patient2_Psi  Patient3_Psi       std
0           1      -        8870          0.25          0.45           0.1  0.175594
1           4      -        9674          0.92          1.00           0.4  0.325781

建议?

3 个答案:

答案 0 :(得分:1)

您可以这样操作,使用filter进行与模式匹配的列过滤:

df = df.replace('NaN', np.nan)
df_new = df[~df.filter(like='Patient').isna().any(axis=1)]
pd.concat([df_new, df_new.filter(like='Patient').std(axis=1).rename('std')], axis=1)

输出:

   chromosome strand  elementloc  Patient1_Psi  Patient2_Psi  Patient3_Psi       std
1           1      -        8870          0.25          0.45           0.1  0.175594
3           4      -        9674          0.92          1.00           0.4  0.325781

答案 1 :(得分:1)

只需用熊猫语翻译您的要求,就可以单行完成

df[(df.loc[:, 'Patient1_Psi':] == 'NaN').sum(axis=1) < 2]

它给出了预期的结果:

   chromosome strand  elementloc Patient1_Psi Patient2_Psi Patient3_Psi
1           1      -        8870         0.25         0.45          0.1
3           4      -        9674         0.92            1          0.4

顺便说一句,如果您使用的是正确的NaN值而不是字符串表示形式,则可以使用

df[df.loc[:, 'Patient1_Psi':].isna().sum(axis=1) < 2]

答案 2 :(得分:0)

您可以将dropnasubset列名列表一起使用。即根据子集列考虑哪些行需要删除:

df.columns.difference将选择未通过列列表的其余列。

df.replace('NaN', np.nan, inplace=True)
df.dropna(subset=['Patient1_Psi', 'Patient2_Psi','Patient3_Psi'], axis=0, inplace=True)
df["std"] = df[df.columns.difference(['chromosome','strand', 'elementloc'])].std(axis=1)
print(df)