熊猫保持最完整的行

时间:2017-10-20 00:52:35

标签: python pandas missing-data pandas-groupby

假设我的数据框中有大量缺失数据:

df = pd.DataFrame({'id': ['a','a','b','b','b','c','d','e','e','e'],
                   'q1': [1,1,np.NaN,np.NaN,0,np.NaN,1,np.NaN,1,0],
                   'q2': ['low',np.NaN,np.NaN,'high','low','high','high',np.NaN,np.NaN,'low'],
                   'q3': [np.NaN,1,np.NaN,1,0,0,1,0,np.NaN,np.NaN]
                   })

看起来像这样:

  id   q1    q2   q3
0  a  1.0   low  NaN
1  a  1.0   NaN  1.0
2  b  NaN   NaN  NaN
3  b  NaN  high  1.0
4  b  0.0   low  0.0
5  c  NaN  high  0.0
6  d  1.0  high  1.0
7  e  NaN   NaN  0.0
8  e  1.0   NaN  NaN
9  e  0.0   low  NaN

我想创建一个新的数据帧,每个id只包含一行,但该行是最完整的(NaN的最少实例),但如果它们同样完整,那么当前第一次出现排序顺序

理想输出是一个新的数据帧:

  id   q1    q2   q3
0  a  1.0   low  NaN
1  b  0.0   low  0.0
2  c  NaN  high  0.0
3  d  1.0  high  1.0
4  e  0.0   low  NaN

我可以使用df.isnull().sum(axis=1)计算每行中NA的数量,但我不知道如何使用它来选择具有最小总和的行,特别是如果有超过2个条目用于id

3 个答案:

答案 0 :(得分:2)

您可以使用代理列根据计数进行排序,并使用groupby进行过滤。

df = df.assign(count=df.isnull().sum(1))\
       .sort_values(['id', 'count'])\
       .groupby('id', as_index=0).head(1)\
       .drop('count', 1)

print(df)
  id   q1    q2   q3
0  a  1.0   low  NaN
4  b  0.0   low  0.0
5  c  NaN  high  0.0
6  d  1.0  high  1.0
9  e  0.0   low  NaN

答案 1 :(得分:2)

这就是我要做的事情,drop_duplicates,您可以通过提起Notnullvalue来删除.drop('Notnullvalue',1)

df['Notnullvalue']=df.isnull().sum(1)
df.sort_values(['id','Notnullvalue']).drop_duplicates(['id'],keep='first')
Out[15]: 
  id   q1    q2   q3  Notnullvalue
0  a  1.0   low  NaN             1
4  b  0.0   low  0.0             0
5  c  NaN  high  0.0             1
6  d  1.0  high  1.0             0
9  e  0.0   low  NaN             1

答案 2 :(得分:0)

受@COLDSPEED的启发,我有这样的解决方案。注意na_position='last'sort_values中的默认设置。

df.sort_values(by=['q1','q2','q3'], na_position='last').groupby('id').head(1).sort_index()