折叠 Pandas 行以消除 NaN 条目

时间:2021-05-24 20:55:26

标签: python pandas dataframe numpy collapse

让我们考虑以下 DataFrame

<头>
姓名 A B C D
汤姆 10.0 NaN NaN NaN
汤姆 NaN 15.0 NaN NaN
汤姆 NaN NaN 20.0 NaN
汤姆 NaN NaN NaN 25.0
汤姆 30.0 NaN NaN NaN
汤姆 NaN NaN NaN 40.0
约翰 1.0 NaN NaN NaN
约翰 NaN 2.0 NaN NaN
约翰 NaN NaN 3.0 NaN
约翰 NaN NaN NaN 4.0
约翰 5.0 NaN NaN NaN
约翰 NaN 6.0 NaN NaN
约翰 NaN NaN 7.0 NaN
约翰 NaN NaN NaN 8.0

我想折叠它以限制 DataFrame 中 NaN 值的数量 - 可以是连续的,即如果可能的话合并相邻的行,但我关心的是列 {{1} 的值} 对应折叠后的同一个A-D

我最完美的结果是

<头>
姓名 A B C D
汤姆 10.0 15.0 20.0 25.0
汤姆 30.0 NaN NaN 40.0
约翰 1.0 2.0 3.0 4.0
约翰 5.0 6.0 7.0 8.0

据我所知,Pandas Name 不会成功,因为它会为每个名称留下一个条目。

如果这有帮助,我会使用字典来创建数据框。字典是这样的:

groupby('Name')

所以,基本上,我取字典中的每个数字,然后用这个数字创建一行,然后合并所有行。

是否有一种简单的方法来折叠生成的 DataFrame 或在给定这样的字典的情况下构建更紧凑的 DataFrame

1 个答案:

答案 0 :(得分:2)

您可以 .groupby + .transform(您可以在其中“向上移动”值)。然后删除包含所有 NaN 值的行:

print(
    df.set_index("Name")
    .groupby(level=0)
    .transform(lambda x: sorted(x, key=lambda k: pd.isna(k)))
    .dropna(axis=0, how="all")
    .reset_index()
)

打印:

   Name     A     B     C     D
0   tom  10.0  15.0  20.0  25.0
1   tom  30.0   NaN   NaN  40.0
2  john   1.0   2.0   3.0   4.0
3  john   5.0   6.0   7.0   8.0