如何通过列条件python在数据帧中添加行

How to add rows in a dataframe by a column condition python

提问人:Cristina Dominguez Fernandez 提问时间:11/9/2023 最后编辑:CorralienCristina Dominguez Fernandez 更新时间:11/9/2023 访问量:35

问:

我有一个这样的数据帧:

df = pd.DataFrame({'year': [2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022],

'month': [1,2,3,1,2,3,4,5,6,7,8,9,10,11,1,2,3,4,5],
'client':[1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3],
'total':[10,20,30,55,4,64,88,5,64,32,84,24,69,70,54,11,37,98,52]})
 df

    year  month  client  total
0   2022      1       1     10
1   2022      2       1     20
2   2022      3       1     30
3   2022      1       2     55
4   2022      2       2      4
5   2022      3       2     64
6   2022      4       2     88
7   2022      5       2      5
8   2022      6       2     64
9   2022      7       2     32
10  2022      8       2     84
11  2022      9       2     24
12  2022     10       2     69
13  2022     11       2     70
14  2022      1       3     54
15  2022      2       3     11
16  2022      3       3     37
17  2022      4       3     98
18  2022      5       3     52

我希望所有客户都有 12 个月,因此我需要添加此行并将值 0 分配给列总数。对于此新行,year 列的值是已填满月份的行的副本。

欲望输出:

df = pd.DataFrame({'year': [2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,20 
 22,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022,2022],

'month': [1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12],
'client':[1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3],
'total': 
[10,20,30,0,0,0,0,0,0,0,0,0,55,4,64,88,5,64,32,84,24,69,70,0,54,11,37,98,52,0,0,0,0,0,0,0]})
df
    year  month  client  total  
0   2022      1       1     10
1   2022      2       1     20
2   2022      3       1     30
3   2022      4       1      0
4   2022      5       1      0
5   2022      6       1      0
6   2022      7       1      0
7   2022      8       1      0
8   2022      9       1      0
9   2022     10       1      0
10  2022     11       1      0
11  2022     12       1      0
12  2022      1       2     55
13  2022      2       2      4
14  2022      3       2     64
15  2022      4       2     88
16  2022      5       2      5
17  2022      6       2     64
18  2022      7       2     32
19  2022      8       2     84
20  2022      9       2     24
21  2022     10       2     69
22  2022     11       2     70
23  2022     12       2      0
24  2022      1       3     54
25  2022      2       3     11
26  2022      3       3     37
27  2022      4       3     98
28  2022      5       3     52
29  2022      6       3      0
30  2022      7       3      0
31  2022      8       3      0
32  2022      9       3      0
33  2022     10       3      0
34  2022     11       3      0
35  2022     12       3      0

也许通过合并选项有解决方案?我试过了,但没有一个好的结果

Python 添加

评论

0赞 Corralien 11/9/2023
我修复了您的输入数据。根据预期的输出,第 #14 行应该是客户端 3 而不是 2。

答:

0赞 Corralien 11/9/2023 #1

这不是最简单的方法,但它适用于:pivot_table

out = (df.pivot_table(index=['year', 'client'], columns='month',
                      values='total', fill_value=0.)
         .reindex(columns=range(1, 13), fill_value=0.)
         .stack().swaplevel('month', 'client')
         .rename('total').reset_index())

输出:

>>> out
    year  month  client  total
0   2022      1       1   10.0
1   2022      2       1   20.0
2   2022      3       1   30.0
3   2022      4       1    0.0
4   2022      5       1    0.0
5   2022      6       1    0.0
6   2022      7       1    0.0
7   2022      8       1    0.0
8   2022      9       1    0.0
9   2022     10       1    0.0
10  2022     11       1    0.0
11  2022     12       1    0.0
12  2022      1       2   55.0
13  2022      2       2    4.0
14  2022      3       2   64.0
15  2022      4       2   88.0
16  2022      5       2    5.0
17  2022      6       2   64.0
18  2022      7       2   32.0
19  2022      8       2   84.0
20  2022      9       2   24.0
21  2022     10       2   69.0
22  2022     11       2   70.0
23  2022     12       2    0.0
24  2022      1       3   54.0
25  2022      2       3   11.0
26  2022      3       3   37.0
27  2022      4       3   98.0
28  2022      5       3   52.0
29  2022      6       3    0.0
30  2022      7       3    0.0
31  2022      8       3    0.0
32  2022      9       3    0.0
33  2022     10       3    0.0
34  2022     11       3    0.0
35  2022     12       3    0.0

透视后,数据帧如下所示:

>>> (df.pivot_table(index=['year', 'client'], columns='month',
                    values='total', fill_value=0)
       .reindex(columns=range(1, 13), fill_value=0))

month          1     2     3     4     5     6     7     8     9     10    11  12
year client                                                                      
2022 1       10.0  20.0  30.0   0.0   0.0   0.0   0.0   0.0   0.0   0.0   0.0   0
     2       55.0   4.0  64.0  88.0   5.0  64.0  32.0  84.0  24.0  69.0  70.0   0
     3       54.0  11.0  37.0  98.0  52.0   0.0   0.0   0.0   0.0   0.0   0.0   0

评论

0赞 Cristina Dominguez Fernandez 11/9/2023
唯一的问题是,第一个月的总价值在透视后发生了变化。对于客户端 2,该值为 55,已更改为 54.5,对于客户端 3,该值为 54,并且已更改为 0。
0赞 Corralien 11/9/2023
检查您的数据 Row#14。2022-01 年应该是客户端 3,而不是 2。如果我从我这边修复数据,它就可以工作,您现在可以检查输出吗?
0赞 Cristina Dominguez Fernandez 11/9/2023
非常感谢。现在是正确的。
1赞 Nikhil Belure 11/9/2023 #2

生成包含“year”、“month”和“client”所有可能组合的 DataFrame

all_combinations = pd.DataFrame([(y, m, c) for y in df['year'].unique() for m in range(1, 13) for c in df['client'].unique()], columns=['year', 'month', 'client'])

将原始 DataFrame 与生成的组合合并,在“total”列中用 0 填充 NaN 值

result_df = pd.merge(all_combinations, df, on=['year', 'month', 'client'], how='left').fillna({'total': 0})

按“client”、“year”和“month”对 DataFrame 进行排序,以获得整洁的显示效果

result_df = result_df.sort_values(by=['client', 'year', 'month']).reset_index(drop=True)