Pandas 在 groupby 列中用 NaN 填充组时删除单元格
Pandas deleting cells when filling groups with NaN in groupby column
我试图通过将已知值传播到同一组内的值来填充 DataFrame 中的空行。当分组的所有列都已满时,这似乎工作正常,但如果列中有空单元格,Pandas 将删除值。在提供的示例中,DataFrame 在索引 6 和 8 的“B”列中具有 NaN。在组上使用 ffill
和 bfill
后,第 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
默认情况下groupby
会忽略组键列包含NaN
值的行,所以你不能依赖索引对齐(df[cols_to_fill] = ...
)来更新我们这里的dataframe必须明确 update
原始数据框与 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
我试图通过将已知值传播到同一组内的值来填充 DataFrame 中的空行。当分组的所有列都已满时,这似乎工作正常,但如果列中有空单元格,Pandas 将删除值。在提供的示例中,DataFrame 在索引 6 和 8 的“B”列中具有 NaN。在组上使用 ffill
和 bfill
后,第 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
默认情况下groupby
会忽略组键列包含NaN
值的行,所以你不能依赖索引对齐(df[cols_to_fill] = ...
)来更新我们这里的dataframe必须明确 update
原始数据框与 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