【问题标题】:Count similar string values in pandas dataframe per year每年计算熊猫数据框中的相似字符串值
【发布时间】:2020-06-08 11:19:38
【问题描述】:

有下面的数据集。我想计算某年某个字符串的出现次数。实际上,我多年来拥有更大的数据框。如何结合 groupby 方法并计算不同的字符串值?

df = pd.DataFrame(data={'col1':['A','B','D','A'],'col2':['B','C','E','E'],'col3':['C','D','',''],'col4':['D','E','','']},index = ['01-01-2000','02-01-2000','01-01-2001','02-01-2001'])

           col1 col2 col3 col4
01-01-2000    A    B    C    D
02-01-2000    B    C    D    E
01-01-2001    D    E          
02-01-2001    A    E          

想要的结果:

           count
A    2000    1
A    2001    1
B    2000    2    
B    2001    0
C    2000    2
C    2001    0
D    2000    2
D    2001    1
E    2000    1
E    2001    2

【问题讨论】:

  • 您的示例代码不会在您的帖子中生成示例 df...
  • 代码生成的数据框与您显示的不同。

标签: python pandas pivot-table


【解决方案1】:

您可以在DataFrame.assign 中创建新列year,然后通过DataFrame.melt 重塑,通过DataFrame.query 删除空字符串,通过GroupBy.size 获取计数,通过Series.unstackDataFrame.stack 添加缺少的类别和最后使用Series.reset_index

df.index = pd.to_datetime(df.index)

df = (df.assign(year = df.index.year)
        .melt('year', value_name='val')
        .query("val != ''")
        .groupby(['val','year'])
        .size()
        .unstack(fill_value=0)
        .stack()
        .reset_index(name='count')
        )
print (df)
  val  year  count
0   A  2000      2
1   A  2001      1
2   B  2000      2
3   B  2001      0
4   C  2000      2
5   C  2001      0
6   D  2000      1
7   D  2001      1
8   E  2000      1
9   E  2001      2

【讨论】:

    【解决方案2】:

    首先,让我们将空单元格替换为空值(例如,np.nan),并将索引设置为datetime index

    import pandas as pd
    import numpy as np
    df = pd.DataFrame(data={'col1':['A','B','D','A'],'col2':['B','C','E','E'],'col3':['C','D','',''],'col4':['D','E','','']},index = ['01-01-2000','02-01-2000','01-01-2001','02-01-2001'])
    df.index = pd.DatetimeIndex(df.index)
    df.replace('',np.nan, inplace=True)
    

    (我还更改了代码以适合您问题中的示例)

    要得到你的结果:

    result = df.apply(lambda row: row.value_counts(), axis=1).resample('1Y').sum().stack().reorder_levels([1, 0]).sort_index()
    

    产量:

    A  2000-12-31    1.0
       2001-12-31    1.0
    B  2000-12-31    2.0
       2001-12-31    0.0
    C  2000-12-31    2.0
       2001-12-31    0.0
    D  2000-12-31    2.0
       2001-12-31    1.0
    E  2000-12-31    1.0
       2001-12-31    2.0
    

    让我们分解一下:

    • df.apply(lambda row: row.value_counts(), axis=1) 将您的数据框转换为列中的“A”到“E”,以及单元格中出现的次数:

                  A   B   C   D   E
      2000-01-01  1.0 1.0 1.0 1.0 NaN
      2000-02-01  NaN 1.0 1.0 1.0 1.0
      2001-01-01  NaN NaN NaN 1.0 1.0
      2001-02-01  1.0 NaN NaN NaN 1.0
      
    • .resample('1Y').sum() 正在使用resample,这只是一个花哨的groupby,它可以很好地处理日期时间索引,按年份汇总出现次数。它产生:

                  A   B   C   D   E
      2000-12-31  1.0 2.0 2.0 2.0 1.0
      2001-12-31  1.0 0.0 0.0 1.0 2.0
      
    • stackreorder_levels 和 sort_index 只是将结果转换为所需的格式(嗯,几乎......请注意,它显示的是当年的最后一天,而不是年份)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多