热门标签:
Q:

在groupby列中使用NaN填充组时删除单元格

我试图通过将已知值传播到同一组内的值来填充DataFrame中的空行。 当分组的所有列都已满时,这似乎工作正常,但如果列中有空单元格,Pandas将删除值。 在提供的示例中,DataFrame在索引6和8的列"B"中具有NaN。 在组上使用ffillbfill后,第6行和第8行中的数字已替换为NaN。 如何避免这种意想不到的副作用?

密码:

import pandas as pd
import numpy as np

df = pd.DataFrame({"A": [1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6, 6],
                    "B": ['a', 'a', 'b', 'b', 'b', 'c', np.nan, 'd', 
                          np.nan, 'e', 'e', 'g', 'h', 'h'],
                    "C": [5.0, np.nan, 4.0, 4.0, np.nan, 9.0, np.nan, 
                          np.nan, 9.0, 8.0, np.nan, 2.0, np.nan, 3.0],
                    "D": [1.0, 1.0, np.nan, 2.0, np.nan, np.nan, np.nan, 
                          np.nan, 3.0, 2.0, np.nan, 9.0, np.nan, 3.0],
                    "E": [np.nan, 6.0, np.nan, 3.0, np.nan, np.nan, 7.0, 
                          np.nan, 7.0, 2.0, np.nan, np.nan, np.nan, 0.0]})

cols_to_groupby = ["A", "B"]
cols_to_fill = ["C", "D", "E"]

original_indxs = df.index
df[cols_to_fill] = (
    df.sort_values(cols_to_groupby)[cols_to_fill + cols_to_groupby]
    .groupby(cols_to_groupby)
    .transform(lambda x: x.ffill().bfill())
)

样本数据集:

    A    B    C    D    E
0   1    a  5.0  1.0  NaN
1   1    a  NaN  1.0  6.0
2   2    b  4.0  NaN  NaN
3   2    b  4.0  2.0  3.0
4   2    b  NaN  NaN  NaN
5   3    c  9.0  NaN  NaN
6   3  NaN  NaN  NaN  7.0
7   3    d  NaN  NaN  NaN
8   3  NaN  9.0  3.0  7.0
9   4    e  8.0  2.0  2.0
10  4    e  NaN  NaN  NaN
11  5    g  2.0  9.0  NaN
12  6    h  NaN  NaN  NaN
13  6    h  3.0  3.0  0.0

预期结果:

    A    B    C    D    E
0   1    a  5.0  1.0  6.0
1   1    a  5.0  1.0  6.0
2   2    b  4.0  2.0  3.0
3   2    b  4.0  2.0  3.0
4   2    b  4.0  2.0  3.0
5   3    c  9.0  NaN  NaN
6   3  NaN  NaN  NaN  7.0
7   3    d  NaN  NaN  NaN
8   3  NaN  9.0  3.0  7.0
9   4    e  8.0  2.0  2.0
10  4    e  8.0  2.0  2.0
11  5    g  2.0  9.0  NaN
12  6    h  3.0  3.0  0.0
13  6    h  3.0  3.0  0.0

实际结果:

    A    B    C    D    E
0   1    a  5.0  1.0  6.0
1   1    a  5.0  1.0  6.0
2   2    b  4.0  2.0  3.0
3   2    b  4.0  2.0  3.0
4   2    b  4.0  2.0  3.0
5   3    c  9.0  NaN  NaN
6   3  NaN  NaN  NaN  NaN
7   3    d  NaN  NaN  NaN
8   3  NaN  NaN  NaN  NaN
9   4    e  8.0  2.0  2.0
10  4    e  8.0  2.0  2.0
11  5    g  2.0  9.0  NaN
12  6    h  3.0  3.0  0.0
13  6    h  3.0  3.0  0.0
原网址
A:

默认情况下groupby将忽略组键列包含NaN值的行,因此您不能依赖索引对齐(df[cols_to_fill] = ...)来更新dataframe在这里我们必须显式update原始dataframe与groupby

的结果
cols = df.groupby(cols_to_groupby)[cols_to_fill].apply(lambda x: x.ffill().bfill())
df.update(cols)

    A    B    C    D    E
0   1    a  5.0  1.0  6.0
1   1    a  5.0  1.0  6.0
2   2    b  4.0  2.0  3.0
3   2    b  4.0  2.0  3.0
4   2    b  4.0  2.0  3.0
5   3    c  9.0  NaN  NaN
6   3  NaN  NaN  NaN  7.0
7   3    d  NaN  NaN  NaN
8   3  NaN  9.0  3.0  7.0
9   4    e  8.0  2.0  2.0
10  4    e  8.0  2.0  2.0
11  5    g  2.0  9.0  NaN
12  6    h  3.0  3.0  0.0
13  6    h  3.0  3.0  0.0

相似问题