例如,假设我有一个如下所示的 DataFrame:
df1 = pd.DataFrame({
"grp": ["a", "a", "a", "b", "b", "c", "c", "c", "d"],
"col1": ["1", "2", np.nan, "4", "5", np.nan, "6", "7", np.nan]
})
grp col1
0 a 1
1 a 2
2 a NaN
3 b 4
4 b 5
5 c NaN
6 c 6
7 c 7
8 d NaN
对于列名为 grp
的每个组,我想删除 col1
的行是 NaN。限制是当组中有多行时我不想删除这些行。
我希望输出 DataFrame 看起来像这样。
df2 = pd.DataFrame({
"grp": ["a", "a", "b", "b", "c", "c", "d"],
"col1": ["1", "2", "4", "5", "6", "7", np.nan]
})
# notice the NaN in `grp`=="d"
grp col1
0 a 1
1 a 2
2 b 4
3 b 5
4 c 6
5 c 7
6 d NaN
我设法想出了一个解决方案,但它很笨拙。有没有更简洁的方法来解决这个问题?我也不明白为什么这些值被转换为字符串......df1_grp = df1.groupby("grp")['col1'].apply(np.hstack).to_frame().reset_index()
df1_grp['col1'] = df1_grp['col1'].apply(lambda x: [float(_) for _ in x if _!="nan"] if len(x)>1 else x)
df1_grp.explode('col1')
最佳答案
使用 GroupBy.transform
与 GroupBy.all
用于测试组的所有值是否为 NaN
然后通过 |
链接倒置掩码来自 &
按位 OR
:
m = df1['col1'].isna()
m1 = m.groupby(df1["grp"]).transform('all')
df = df1[~m | m1]
print (df)
grp col1
0 a 1
1 a 2
3 b 4
4 b 5
6 c 6
7 c 7
8 d NaN
或者您可以过滤仅包含缺失值的组:m = df1['col1'].notna()
m1 = df1['grp'].isin(df1.loc[m, 'grp'])
df = df1[m | ~m1]
print (df)
grp col1
0 a 1
1 a 2
3 b 4
4 b 5
6 c 6
7 c 7
8 d NaN
关于python - Pandas - 如何在组内删除 nan 行,但前提是有不止一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68286076/