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()
假设我有一个包含大量缺失数据的数据框:
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
您可以使用替代列根据计数进行排序,并使用 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()