【问题标题】:Count occurences for each year in pandas dataframe based on subgroup根据子组计算熊猫数据框中每年的出现次数
【发布时间】:2018-09-10 19:07:44
【问题描述】:

想象一个由

给出的pandasdataframe
df = pd.DataFrame({
    'id': [1, 1, 1, 2, 2],
    'location': [1, 2, 3, 1, 2],
    'date': [pd.to_datetime('01-01-{}'.format(year)) for year in [2015, 2016, 2015, 2017, 2018]]
}).set_index('id')

看起来像这样

    location       date
id                     
1          1 2015-01-01
1          2 2016-01-01
1          3 2015-01-01
2          1 2017-01-01
2          2 2018-01-01

现在我想为datecolumn 中表示的每一年创建一个列,计算id 的出现次数。因此生成的数据框应该是这样的

    location       date  2015  2016  2017  2018
id                                             
1          1 2015-01-01     2     1     0     0
1          2 2016-01-01     2     1     0     0
1          3 2015-01-01     2     1     0     0
2          1 2017-01-01     0     0     1     1
2          2 2018-01-01     0     0     1     1

现在我想使用pd.groupby.transform,但我想不出最佳解决方案。


我自己的解决方案是

df['year'] = df['date'].map(lambda x: x.year)
df = pd.merge(
    df, 
    pd.pivot_table(df, 'date', 'id', 'year', 'count').fillna(0).astype(int), 
    left_index=True, right_index=True).drop('year', axis=1)

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    get_dummies

    df.join(pd.get_dummies(df.date.dt.year).sum(level=0))
    
             date  location  2015  2016  2017  2018
    id                                             
    1  2015-01-01         1     2     1     0     0
    1  2016-01-01         2     2     1     0     0
    1  2015-01-01         3     2     1     0     0
    2  2017-01-01         1     0     0     1     1
    2  2018-01-01         2     0     0     1     1
    

    factorize

    i, r = pd.factorize(df.index)
    j, c = pd.factorize(df.date.dt.year)
    n, m = shape = len(r), len(c)
    b = np.zeros(shape, dtype=np.int64)
    np.add.at(b, (i, j), 1)
    
    df.join(pd.DataFrame(b, r, c).rename_axis('id'))
    
             date  location  2015  2016  2017  2018
    id                                             
    1  2015-01-01         1     2     1     0     0
    1  2016-01-01         2     2     1     0     0
    1  2015-01-01         3     2     1     0     0
    2  2017-01-01         1     0     0     1     1
    2  2018-01-01         2     0     0     1     1
    

    【讨论】:

      【解决方案2】:

      sizeunstackyearjoin创建助手DataFrame到原始df

      df1 = df.join(df.groupby(['id', df['date'].dt.year]).size().unstack(fill_value=0), on='id')
      print (df1)
          location       date  2015  2016  2017  2018
      id                                             
      1          1 2015-01-01     2     1     0     0
      1          2 2016-01-01     2     1     0     0
      1          3 2015-01-01     2     1     0     0
      2          1 2017-01-01     0     0     1     1
      2          2 2018-01-01     0     0     1     1
      

      详情:

      print (df.groupby(['id', df['date'].dt.year]).size().unstack(fill_value=0))
      
      date  2015  2016  2017  2018
      id                          
      1        2     1     0     0
      2        0     0     1     1
      

      crosstab 的另一个解决方案:

      df1 = df.join(pd.crosstab(df.index, df['date'].dt.year), on='id')
      
      print (pd.crosstab(df.index, df['date'].dt.year))
      date   2015  2016  2017  2018
      row_0                        
      1         2     1     0     0
      2         0     0     1     1
      

      【讨论】:

        猜你喜欢
        • 2019-05-13
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-12
        • 2020-03-29
        相关资源
        最近更新 更多