我有一个要根据某些条件修改的数据框。实际的数据框(下面的示例中有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
建议?
答案 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)
您可以将dropna
与subset
列名列表一起使用。即根据子集列考虑哪些行需要删除:
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)