【问题标题】:Create column of value_counts in Pandas dataframe在 Pandas 数据框中创建 value_counts 列
【发布时间】:2013-07-16 13:34:45
【问题描述】:

我想从我的 Pandas 数据框列之一创建唯一值计数,然后将具有这些计数的新列添加到我的原始数据框中。我尝试了几种不同的方法。我创建了一个 pandas 系列,然后使用 value_counts 方法计算计数。我试图将这些值合并回我的原始数据框,但我想要合并的键在 Index(ix/loc) 中。

Color Value
Red   100
Red   150
Blue  50

我想返回类似的东西:

Color Value Counts
Red   100   2
Red   150   2 
Blue  50    1

【问题讨论】:

  • 这是最近很流行的问题。请参阅此问题here,这与您的情况几乎相同。

标签: python pandas


【解决方案1】:
df['Counts'] = df.groupby(['Color'])['Value'].transform('count')

例如,

In [102]: df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]})

In [103]: df
Out[103]: 
  Color  Value
0   Red    100
1   Red    150
2  Blue     50

In [104]: df['Counts'] = df.groupby(['Color'])['Value'].transform('count')

In [105]: df
Out[105]: 
  Color  Value  Counts
0   Red    100       2
1   Red    150       2
2  Blue     50       1

请注意,transform('count') 会忽略 NaN。如果要计算 NaN,请使用 transform(len)


致匿名编辑:如果您在使用transform('count') 时遇到错误,可能是因为您的 Pandas 版本太旧。以上适用于 pandas 0.15 或更高版本。

【讨论】:

  • 非常感谢。非常有帮助。我一直在尝试将其应用于更大的 DataFrame 并继续收到此错误“ValueError:错误的项目数通过 1,索引意味着 4”。
  • 尝试只选择一列进行转换,即 df.groupby(['Color'])[].transform('count')
  • 已添加到食谱中:pandas.pydata.org/pandas-docs/dev/cookbook.html#grouping(明天将构建文档)
  • 不确定这是最好的方法,但是 df['new column name'] = df[['col1','col2']].groupby('col1').transform ('count') 似乎解决了我传递错误数量的项目时遇到的问题。
  • 感谢@user2592989,我不明白为什么,但如果你尝试做同样的事情,但计算Value 列而不是(nvm 这是一个糟糕的例子),我得到ValueError: Wrong number of items passed 1, indices imply 2。目前尚不清楚为什么,但这是使用df['Counts'] = df.groupby(['Value', 'Color']).transform('count') 完成的。
【解决方案2】:

另一种选择:

z = df['Color'].value_counts 

z1 = z.to_dict() #converts to dictionary

df['Count_Column'] = df['Color'].map(z1) 

此选项将为您提供一个包含重复计数值的列,对应于“颜色”列中每个值的频率。

【讨论】:

  • 这可以简化为:df['Count_Column'] = df['Color'].map(df['Color'].value_counts())。您可以使用系列来映射(不必是字典)
【解决方案3】:

此答案使用Series.mapSeries.value_counts。已使用 Pandas 1.1 进行了测试。

df['counts'] = df['attribute'].map(df['attribute'].value_counts())

信用:comment by sacuL

【讨论】:

    【解决方案4】:

    df['Counts'] = df.Color.groupby(df.Color).transform('count')

    您可以对任何系列执行此操作:将其单独分组并调用transform('count')

    >>> series = pd.Series(['Red', 'Red', 'Blue'])
    >>> series.groupby(series).transform('count')
    0    2
    1    2
    2    1
    dtype: int64
    

    【讨论】:

      【解决方案5】:

      我最初的想法是使用如下所示的列表理解,但正如评论中所指出的,这比 groupbytransform 方法慢。我将留下这个答案来演示不该做什么

      In [94]: df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]})
      In [95]: df['Counts'] = [sum(df['Color'] == df['Color'][i]) for i in xrange(len(df))]
      In [96]: df
      Out[100]: 
        Color  Value  Counts
      0   Red    100       2
      1   Red    150       2
      2  Blue     50       1
      
      [3 rows x 3 columns]
      

      @unutbu 的方法对于具有多列的 DataFrame 变得复杂,这使得编码更简单。如果您使用的是小型数据框,这会更快(见下文),否则,您应该使用 NOT 使用它。

      In [97]: %timeit df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}); df['Counts'] = df.groupby(['Color']).transform('count')
      100 loops, best of 3: 2.87 ms per loop
      In [98]: %timeit df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}); df['Counts'] = [sum(df['Color'] == df['Color'][i]) for i in xrange(len(df))]
      1000 loops, best of 3: 1.03 ms per loop
      

      【讨论】:

      • 3 行的例子很容易误导时间。尝试使用更大的数据框,您会发现 groupby 方法快得多(我尝试使用您的 df 重复 1000 次(` df = pd.concat([df]*1000 , ignore_index=True)`) 并得到 3.6 ms (gropuby) vs 29 s (list comprehension))。此外,我认为 groupby 方法更简单。
      【解决方案6】:

      创建一个包含重复值计数的列。这些值是从其他列计算的临时计算。非常快。感谢@ZakS。

      sum_A_B = df['A']+df['B']
      sum_A_B_dict = sum_A_B.value_counts().to_dict()
      df['sum_A_B'] = sum_A_B.map(sum_A_B_dict) 
      

      【讨论】:

        猜你喜欢
        • 2017-11-03
        • 2016-09-11
        • 1970-01-01
        • 1970-01-01
        • 2021-12-02
        • 2018-03-05
        • 2018-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多