【问题标题】:transforming DataFrame shape转换 DataFrame 形状
【发布时间】:2020-11-21 17:05:39
【问题描述】:

我想从我的 DataFrame 转换,其中我有 2 年的行,我想比较我有 df 的两年日期值,如下所示。

         Date            item        group       amount
0.       1/2/2019        car         1           110000
1.       20/2/2019       bat         2           2000
2.       10/2/2019       Ring        3           3880
3.       15/2/2019       machine     4           4500
4.       27/2/2019       Radio       5           2400
5.       21/2/2019        car         1           45000
0.       1/2/2020        car         1           130000
1.       20/2/2020       bat         2           2090
2.       10/2/2020       Ring        3           3200
3.       15/2/2020       machine     4           6500
4.       27/2/2020       Radio       5           9900
5.       21/2/2020        car         1           54280

我希望将其转换为数据框,其中包含组的项目应显示在 2019 年每个项目的 2019 年列总金额和 2020 年每个项目在 2020 年的列总金额中。


       item     group      2019         2020
0.    car        1         155000       184280
1.    bat        2         2000         2090
2.    Ring       3         3880         3200
3.    Machine    4         4500         6500
4.    Radio      5         2400         9900

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:
    import pandas as pd
    import numpy as np
    
    df['Year'] = pd.to_datetime(df.Date, format='%d/%m/%Y').dt.year
    pdf = pd.pivot_table(df, values='amount', index=['item', 'group'], columns=['Year'], 
                         aggfunc=np.sum).reset_index(drop=False).sort_values(['group'])
    print(pdf)
    
    Year     item  group    2019    2020
    3         car      1  155000  184280
    2         bat      2    2000    2090
    1        Ring      3    3880    3200
    4     machine      4    4500    6500
    0       Radio      5    2400    9900
    

    Working example

    【讨论】:

      【解决方案2】:

      使用pd.crosstab:

      In [2997]: df.Date = pd.to_datetime(df.Date)
      In [3036]: x = pd.crosstab(index=[df.item, df.group], columns=df.Date.dt.year, values=df.amount, aggfunc='sum').reset_index().sort_values('group')
      
      In [3037]: x
      Out[3037]: 
      Date     item  group    2019    2020
      3         car      1  155000  184280
      2         bat      2    2000    2090
      1        Ring      3    3880    3200
      4     machine      4    4500    6500
      0       Radio      5    2400    9900
      

      或:

      使用df.pivot_table:

      In [2997]: df.Date = pd.to_datetime(df.Date)
      
      In [3024]: x = df.pivot_table(index=['item', 'group'], columns=df.Date.dt.year, values='amount', aggfunc='sum').reset_index().sort_values('group')
      
      In [3025]: x
      Out[3025]: 
      Date     item  group    2019    2020
      3         car      1  155000  184280
      2         bat      2    2000    2090
      1        Ring      3    3880    3200
      4     machine      4    4500    6500
      0       Radio      5    2400    9900
      

      【讨论】:

        【解决方案3】:

        groupby 加上 unstack 可以解决问题:

        (df.assign(Date=df.Date.dt.year)
           .groupby(["Date", "item", "group"])
           .amount
           .sum()
           .unstack("Date")
           .reset_index()
           .rename_axis(columns=None)
         )
        
            
            item    group   2019    2020
        0   Radio   5       2400    9900
        1   Ring    3       3880    3200
        2   bat     2       2000    2090
        3   car     1       155000  184280
        4   machine 4       4500    6500
        

        与基于 pivot_table 的 pivot_table 或交叉表相比,手动控制聚合可以提供一些速度优势。一如既往,测试是验证速度的可靠方法。仅当您需要速度时。

        【讨论】:

        • 它很棒。你能告诉我为什么这里使用 rename_axis(columns=None)...?
        • 去掉列名。如果您停在 rest 索引处,您将看到一个日期名称
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-07
        • 2017-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多