Pandas 保留最完整的行

Pandas keep the most complete rows

假设我有一个包含大量缺失数据的数据框:

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 只包含 1 行,但该行是最完整的(最少的 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 的数量,但我不确定如何使用它然后 select 得出总和最小的行,尤其是如果有id

超过 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

这就是我要做的,drop_duplicates,你可以通过起诉 .drop('Notnullvalue',1)

放弃 Notnullvalue
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

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

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