提问人:Gary Franklin 提问时间:11/17/2023 更新时间:11/17/2023 访问量:37
需要从数据帧中删除具有 NaN 的行 - 但前提是组中还有其他不包含 NaN 的行
Need to delete rows with NaN from dataframe - but only if there are other rows in the group that don't contain NaN
问:
我有一个包含数百万行的数据集,所以我宁愿不要使用循环进行暴力破解。可以按如下方式对问题进行建模:
data = {'A': ['I', 'I', 'I', 'I', 'I', 'I', 'S'],
'B': ['J', 'J', 'J', 'J', 'J', 'J', 'J'],
'C': ['K', 'K', 'K', 'K', 'K', 'K', 'K'],
'D': ['L', 'L', 'L', 'L', 'L', 'L', 'T'],
'E': [np.nan, 'O', 'O', np.nan, 'Q', 'Q', np.nan],
'F': ['M', 'M', 'M', 'M', 'M', 'M', 'M'],
'G': ['N', 'N', 'N', np.nan, 'N', 'N', 'N'],
'H': [np.nan, np.nan, 'P', np.nan, np.nan, 'R', np.nan]}
而我正在寻找的结果是:
A B C D E F G H
0 I J K L O M N P
1 I J K L Q M N R
2 S J K T NaN M N None
如果我按键分组并根据最后一个条目汇总数据,我会得到:
result_df = df.groupby(['A', 'B', 'C', 'D'], as_index=False, dropna = False).last()
A B C D E F G H
0 I J K L Q M N R
1 S J K T None M N None
我以为last()应该只替换NaN行,但是我用df['E'] =='O'丢失了该行。
所以我把 E 列拉进来:
result_df = df.groupby(['A', 'B', 'C', 'D', 'E'], as_index=False, dropna = False).last()
A B C D E F G H
0 I J K L O M N P
1 I J K L Q M N R
2 I J K L NaN M N None
3 S J K T NaN M N None
而且它不会对 df['E'] == NaN 所在的行进行核弹攻击。
答:
1赞
mozway
11/17/2023
#1
IIUC,你可以在对值进行排序后(使用 sort_values
)进行 groupby.ffill
,然后加入
原始 DataFrame。这使您能够识别重复
的行,而不考虑 NaN:
group = ['A', 'B', 'C', 'D']
tmp = (df
.sort_values(by=list(df))
.groupby(group, as_index=False)
.ffill()
.join(df[group])
)
out = df[~tmp.duplicated().reindex(df.index)]
输出:
A B C D E F G H
2 I J K L O M N P
5 I J K L Q M N R
6 S J K T NaN M N NaN
中间:tmp
E F G H A B C D
2 O M N P I J K L
1 O M N P I J K L
5 Q M N R I J K L
4 Q M N R I J K L
0 Q M N R I J K L
3 Q M N R I J K L
6 NaN M N NaN S J K T
评论
1赞
Gary Franklin
11/17/2023
明!我对duplicated()有一些研究要学习。谢谢!!!
评论