【问题标题】:Using groupby on a Pandas DataFrame to add arbitrary number of columns and calculate values [duplicate]在 Pandas DataFrame 上使用 groupby 添加任意数量的列并计算值 [重复]
【发布时间】:2018-09-19 04:09:11
【问题描述】:

我有一个 pandas DataFrame,我想通过使用 groupby 并根据小时时间增量添加任意数量的列,并从第三列填充数据,将其转换为时间表(用于可视化目的)。

源 DataFrame 可能如下所示:

ID  Hour Floor          
Jay  2     34       
Jay  3     34   
Tim  0     36  
Tim  1     34
Tim  2     36
Tom  3     32
Tom  4     36
Rob  3     31
Rob  4     32
Rob  5     33
Rob  6     34
...

我的目标是:

ID  HOUR_0 HOUR_1 HOUR_2 HOUR_3 HOUR_4 HOUR_5 HOUR_6...
Jay   0      0      34      34      0      0      0
Tim   36     34     36      0       0      0      0
Tom   0      0      0       32      36     0      0
Rob   0      0      0       31      32     33     34

我无法得到的(不使用循环手动构建它)是根据第一个 DataFrame 中的唯一性或小时范围添加任意数量的列(在 groupby 操作之后),然后基于计算每个列的值在第一个 DataFrame 的 Hour 和 Floor 列上。

有什么想法吗?

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    因为我忍不住要展示它是如何与pd.factorize 一起工作的

    i, r = pd.factorize(df.ID)
    j, c = pd.factorize(df.Hour, sort=True)
    b = np.zeros((r.size, c.size), df.Floor.dtype)
    
    b[i, j] = df.Floor.values
    
    d = pd.DataFrame(b, r, [f'Hour_{h}' for h in c])
    
    d
    
         Hour_0  Hour_1  Hour_2  Hour_3  Hour_4  Hour_5  Hour_6
    Jay       0       0      34      34       0       0       0
    Tim      36      34      36       0       0       0       0
    Tom       0       0       0      32      36       0       0
    Rob       0       0       0      31      32      33      34
    

    【讨论】:

      【解决方案2】:

      这是简单的支点吗?

      df.pivot(*df.columns).fillna(0).add_prefix('Hour_')
      Out[71]: 
      Hour  Hour_0  Hour_1  Hour_2  Hour_3  Hour_4  Hour_5  Hour_6
      ID                                                          
      Jay      0.0     0.0    34.0    34.0     0.0     0.0     0.0
      Rob      0.0     0.0     0.0    31.0    32.0    33.0    34.0
      Tim     36.0    34.0    36.0     0.0     0.0     0.0     0.0
      Tom      0.0     0.0     0.0    32.0    36.0     0.0     0.0
      

      【讨论】:

      • 是的,应该考虑一下。如果顺序不同,解压缩可能会导致问题。并且可能需要添加.astype(int)。赞成
      • @AntonvBR 是的,应该在这里添加 astype(int) :-)
      【解决方案3】:

      您正在寻找unstack()。但首先我们需要set_index():

      df = df.set_index(['ID','Hour']).unstack(fill_value=0).add_prefix('HOUR_')
      df.columns = df.columns.get_level_values(1)
      

      或者按照 Wen 的建议使用枢轴:

      df = (df.pivot(index='ID', columns='Hour', values='Floor')
              .fillna(0)
              .astype(int)
              .add_prefix('HOUR_'))
      

      完整示例:

      import pandas as pd
      
      data = '''\
      ID  Hour Floor          
      Jay  2     34       
      Jay  3     34   
      Tim  0     36  
      Tim  1     34
      Tim  2     36
      Tom  3     32
      Tom  4     36
      Rob  3     31
      Rob  4     32
      Rob  5     33
      Rob  6     34'''
      
      # Recreate dataframe
      df = pd.read_csv(pd.compat.StringIO(data), sep='\s+')
      
      # Apply solution
      df = df.set_index(['ID','Hour']).unstack(fill_value=0).add_prefix('HOUR_')
      df.columns = df.columns.get_level_values(1)
      

      Df 现在是:

           HOUR_0  HOUR_1  HOUR_2  HOUR_3  HOUR_4  HOUR_5  HOUR_6
      ID                                                         
      Jay       0       0      34      34       0       0       0
      Rob       0       0       0      31      32      33      34
      Tim      36      34      36       0       0       0       0
      Tom       0       0       0      32      36       0       0
      

      【讨论】:

        猜你喜欢
        • 2021-01-06
        • 1970-01-01
        • 2013-07-14
        • 2017-08-18
        • 1970-01-01
        • 1970-01-01
        • 2019-10-01
        • 2017-01-26
        相关资源
        最近更新 更多