首页 > 解决方案 > pd 数据框按 id 添加行

问题描述

我有一些 id、天数和运行总和的 df:

data = {'id': [0, 0, 0, 1, 1, 2, 1], 'day' : [0, 2, 1, 1, 4, 2, 2], 'running_sum': [1,4,2,1,6,6,3]}
df_1 = pd.DataFrame(data)


    id  day running_sum
0   0   0   1
1   0   2   4
2   0   1   2
3   1   1   1
4   1   4   6
5   2   2   6
6   1   2   3

我想为每个 id 拥有所有日子的数据框,并具有正确的运行总和:

    id  day running_sum
0   0   0   1
1   0   1   2
2   0   2   4
3   0   3   4
4   0   4   4
5   1   0   0
6   1   1   1
7   1   2   3
8   1   3   3
9   1   4   6
10  2   0   0
11  2   1   0
12  2   2   6
13  2   3   6
14  2   4   6

谢谢您的帮助

标签: pythonpandas

解决方案


让我们看看这个逻辑是不是你的想法:

设置idday作为索引:

df_1 = df_1.set_index(['id', 'day'])

df_1在引入新数字的同时建立一个新的索引来重新索引;幸运的是索引是唯一的,所以 reindex 工作正常:

new_index = df_1.index.get_level_values('id').unique()

new_index = pd.MultiIndex.from_product([new_index, range(5)],
                                       names = ['id', 'day'])

df_1 = df_1.reindex(new_index)

Groupbyid和 filldown 在每个组上,其余的 null 将被替换为零:

(df_1.assign(running_sum = df_1.groupby('id')
                               .running_sum
                               .ffill()
                               .fillna(0))
     .reset_index()
)

    id  day  running_sum
0    0    0          1.0
1    0    1          2.0
2    0    2          4.0
3    0    3          4.0
4    0    4          4.0
5    1    0          0.0
6    1    1          1.0
7    1    2          3.0
8    1    3          3.0
9    1    4          6.0
10   2    0          0.0
11   2    1          0.0
12   2    2          6.0
13   2    3          6.0
14   2    4          6.0

如果您不反对使用附加库,那么pyjanitor的完整功能/方法可以帮助抽象该过程:

# pip install pyjanitor
import pyjanitor
df = df_1.complete('id', {'day':range(5)}) # explicitly expose the missing values

df.assign(running_sum = df.groupby('id').running_sum.ffill().fillna(0))

    id  day  running_sum
0    0    0          1.0
1    0    1          2.0
2    0    2          4.0
3    0    3          4.0
4    0    4          4.0
5    1    0          0.0
6    1    1          1.0
7    1    2          3.0
8    1    3          3.0
9    1    4          6.0
10   2    0          0.0
11   2    1          0.0
12   2    2          6.0
13   2    3          6.0
14   2    4          6.0

所有这一切都是以我的逻辑正确的假设为前提的


推荐阅读