如何在pandas中聚合多个列?

2024-05-29 03:11:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我以前在这里也问过类似的问题 How to get aggregate of data from multiple dates in pandas?

但我的问题稍微复杂一点

import pandas as pd
import numpy as np

df = pd.DataFrame(data={'name':['a', 'b', 'c', 'd', 'e', 'f'],
                        'vaccine_1':['2021-01-20', '2021-01-20', '2021-02-20', np.nan, '2021-02-22', '2021-02-23'],
                        'vaccine_2':['2021-02-22', '2021-02-22', '2021-02-25', np.nan, '2021-03-22', np.nan], 
                        'vaccine_type': ['AZ', 'AZ', 'AZ', np.nan, 'Sinovac', 'Sinovac'],
                        'gender':['F', 'M', 'F', 'F', 'M', 'M']})

df['vaccine_1'] = pd.to_datetime(df['vaccine_1']).dt.date
df['vaccine_2'] = pd.to_datetime(df['vaccine_2']).dt.date
df

我想要一张这样的桌子

date | F | M | vaccine_type | vaccine_1_total | vaccine_2_total |

我的原始表格要比这复杂得多,有更多的数据,但我想总结了我的意思

多亏了我上一个问题的答案,我可以用熊猫融化来确定正确的日期

out = df.melt(var_name='vaccine', value_name='date', value_vars=['vaccine_1', 'vaccine_2'])
print(pd.crosstab(out['date'], out['vaccine']))

输出:

vaccine     vaccine_1  vaccine_2
date 
2021-01-20          2          0
2021-02-20          1          0
2021-02-22          1          2
2021-02-23          1          0
2021-02-25          0          1
2021-03-22          0          1

但我不知道如何修改它来满足我的需要。有什么想法吗?谢谢

编辑:

所需数据帧

date        | F | M | vaccine_type | vaccine_1_total | vaccine_2_total 
'2021-01-20'| 1 | 1 | AZ           | 2               | 0 
'2021-02-20'| 1 | 0 | AZ           | 1               | 0 
'2021-02-22'| 1 | 1 | AZ           | 1               | 1 
'2021-02-22'| 1 | 0 | Sinovac      | 1               | 0  

等等

所以我认为它应该是groupby和melt的组合?我可以使用groupby来获取非日期列,但是如何将其与melt结合起来呢


Tags: tonamedfdatadatetypenpnan
1条回答
网友
1楼 · 发布于 2024-05-29 03:11:13

您可以首先创建一个包含性别和疫苗数量的表,然后合并不同指标的总和:

df2 = (df.melt(id_vars=['gender', 'vaccine_type'],
               value_vars=['vaccine_1', 'vaccine_2'],
               var_name='vaccine', value_name='date')
         .groupby(['date', 'vaccine_type', 'gender']).agg({'vaccine': 'value_counts'})
         .rename(columns={'vaccine': 'count'})
         .reset_index()
         .pivot_table(index=['date', 'vaccine_type'], columns=['gender', 'vaccine'], values='count', fill_value=0)
        )

pd.merge(df2.sum(level=0, axis=1).reset_index(),
         df2.sum(level=1, axis=1).reset_index(),
         on=['date', 'vaccine_type']
        )

输出:

         date vaccine_type  F  M  vaccine_1  vaccine_2
0  2021-01-20           AZ  1  1          2          0
1  2021-02-20           AZ  1  0          1          0
2  2021-02-22           AZ  1  1          0          2
3  2021-02-22      Sinovac  0  1          1          0
4  2021-02-23      Sinovac  0  1          1          0
5  2021-02-25           AZ  1  0          0          1
6  2021-03-22      Sinovac  0  1          0          1

中间输出(df2):

gender                          F                   M          
vaccine                 vaccine_1 vaccine_2 vaccine_1 vaccine_2
date       vaccine_type                                        
2021-01-20 AZ                   1         0         1         0
2021-02-20 AZ                   1         0         0         0
2021-02-22 AZ                   0         1         0         1
           Sinovac              0         0         1         0
2021-02-23 Sinovac              0         0         1         0
2021-02-25 AZ                   0         1         0         0
2021-03-22 Sinovac              0         0         0         1

相关问题 更多 >

    热门问题