2017-10-20 39 views
2

可以说我有,有很多丢失的数据的数据帧:熊猫保持最完整的行

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的最少实例),但是如果它们同样完整,则以当前排序次序第一次出现

Ide人输出是一个新的数据框:

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

回答

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 
+0

啊有意思。如果2行具有相同的“count”,那么如何选择哪行保留? – Simon

+0

@Simon它应该是第一个项目,假定sort_values按预期执行。 –

2

这就是我要做的事情,drop_duplicates,您可以通过起诉.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 
0

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

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