python - Pandas - 如何在组内删除 nan 行,但前提是有不止一行

标签 python pandas pandas-groupby

例如,假设我有一个如下所示的 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/

相关文章:

python - 在 Pandas 中使用替换同时 ffill 和 bfill

python - 为什么 pandas df.loc + lambda 不起作用?

python - Pandas :按最大值分组和对组求和的最快方法

python - 在带有日期索引的 Pandas 中删除一行,python

python - 如何使用Python区分信号的下降沿?

python - 使用 pandas 中现有数据框的 group 的简单组合创建 df

python - 如何找出 python pandas dataframe 列(日期格式)中的空白?

python - 在 Python 3 中使用 "Break"控制流

python - 当有更多任务时,许多分布式任务 worker 在一次评估后闲置,或者从未收到任何工作

python - 客户先前默认值的滚动计数