【问题标题】:Frequency table for a single variable单个变量的频率表
【发布时间】:2012-08-25 19:09:30
【问题描述】:

当天最后一个新手 pandas 问题:如何为单个系列生成表格?

例如:

my_series = pandas.Series([1,2,2,3,3,3])
pandas.magical_frequency_function( my_series )

>> {
     1 : 1,
     2 : 2, 
     3 : 3
   }

大量的谷歌搜索使我找到了 Series.describe() 和 pandas.crosstabs,但这些都不能满足我的需要:一个变量,按类别计数。哦,如果它适用于不同的数据类型会很好:字符串、整数等。

【问题讨论】:

    标签: python statistics pandas frequency


    【解决方案1】:

    用于具有过多值的变量的频率分布 您可以折叠类中的值,

    这里我对employrate变量的值过高,直接values_count(normalize=True)的频率分布没有意义

                    country  employrate alcconsumption
    0           Afghanistan   55.700001            .03
    1               Albania   11.000000           7.29
    2               Algeria   11.000000            .69
    3               Andorra         nan          10.17
    4                Angola   75.699997           5.57
    ..                  ...         ...            ...
    208             Vietnam   71.000000           3.91
    209  West Bank and Gaza   32.000000               
    210         Yemen, Rep.   39.000000             .2
    211              Zambia   61.000000           3.56
    212            Zimbabwe   66.800003           4.96
    
    [213 rows x 3 columns]
    

    没有分类的values_count(normalize=True)的频率分布,这里的结果长度是139(作为频率分布似乎没有意义):

    print(gm["employrate"].value_counts(sort=False,normalize=True))
    
    50.500000   0.005618
    61.500000   0.016854
    46.000000   0.011236
    64.500000   0.005618
    63.500000   0.005618
    
    58.599998   0.005618
    63.799999   0.011236
    63.200001   0.005618
    65.599998   0.005618
    68.300003   0.005618
    Name: employrate, Length: 139, dtype: float64
    

    放置分类我们将所有值放在一定范围内,即。

    0-10 为 1,
    11-20 为 2
    21-30 为 3,依此类推。
    gm["employrate"]=gm["employrate"].str.strip().dropna()  
    gm["employrate"]=pd.to_numeric(gm["employrate"])
    gm['employrate'] = np.where(
       (gm['employrate'] <=10) & (gm['employrate'] > 0) , 1, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=20) & (gm['employrate'] > 10) , 1, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=30) & (gm['employrate'] > 20) , 2, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=40) & (gm['employrate'] > 30) , 3, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=50) & (gm['employrate'] > 40) , 4, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=60) & (gm['employrate'] > 50) , 5, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=70) & (gm['employrate'] > 60) , 6, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=80) & (gm['employrate'] > 70) , 7, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=90) & (gm['employrate'] > 80) , 8, gm['employrate']
       )
    gm['employrate'] = np.where(
       (gm['employrate'] <=100) & (gm['employrate'] > 90) , 9, gm['employrate']
       )
    print(gm["employrate"].value_counts(sort=False,normalize=True))
    

    分类后我们有一个清晰的频率分布。 在这里我们可以很容易地看到,37.64% 的国家/地区的就业率在51-60% 之间 和11.79% 的国家/地区的就业率在71-80% 之间

    5.000000   0.376404
    7.000000   0.117978
    4.000000   0.179775
    6.000000   0.264045
    8.000000   0.033708
    3.000000   0.028090
    Name: employrate, dtype: float64
    

    【讨论】:

      【解决方案2】:

      @DSM 提供的答案简单明了,但我想我会在这个问题中添加自己的意见。如果您查看pandas.value_counts 的代码,您会发现其中发生了很多事情。

      如果您需要计算多个系列的频率,这可能需要一段时间。更快的实现是使用numpy.uniquereturn_counts = True

      这是一个例子:

      import pandas as pd
      import numpy as np
      
      my_series = pd.Series([1,2,2,3,3,3])
      
      print(my_series.value_counts())
      3    3
      2    2
      1    1
      dtype: int64
      

      注意这里返回的项目是 pandas.Series

      相比之下,numpy.unique 返回一个包含两个项目的元组,唯一值和计数。

      vals, counts = np.unique(my_series, return_counts=True)
      print(vals, counts)
      [1 2 3] [1 2 3]
      

      然后您可以将它们组合成字典:

      results = dict(zip(vals, counts))
      print(results)
      {1: 1, 2: 2, 3: 3}
      

      然后变成pandas.Series

      print(pd.Series(results))
      1    1
      2    2
      3    3
      dtype: int64
      

      【讨论】:

        【解决方案3】:

        您可以在数据框上使用列表推导来计算列的频率

        [my_series[c].value_counts() for c in list(my_series.select_dtypes(include=['O']).columns)]
        

        细分:

        my_series.select_dtypes(include=['O']) 
        

        只选择分类数据

        list(my_series.select_dtypes(include=['O']).columns) 
        

        把上面的列变成一个列表

        [my_series[c].value_counts() for c in list(my_series.select_dtypes(include=['O']).columns)] 
        

        遍历上面的列表并将 value_counts() 应用于每一列

        【讨论】:

          【解决方案4】:

          也许.value_counts()

          >>> import pandas
          >>> my_series = pandas.Series([1,2,2,3,3,3, "fred", 1.8, 1.8])
          >>> my_series
          0       1
          1       2
          2       2
          3       3
          4       3
          5       3
          6    fred
          7     1.8
          8     1.8
          >>> counts = my_series.value_counts()
          >>> counts
          3       3
          2       2
          1.8     2
          fred    1
          1       1
          >>> len(counts)
          5
          >>> sum(counts)
          9
          >>> counts["fred"]
          1
          >>> dict(counts)
          {1.8: 2, 2: 2, 3: 3, 1: 1, 'fred': 1}
          

          【讨论】:

          • .value_counts().sort_index(1) ,以防止第一列可能出现轻微乱序
          • DataFrame 是否有等价物,而不是系列?我尝试在 df 上运行 .value_counts() 并得到AttributeError: 'DataFrame' object has no attribute 'value_counts'
          • 有没有一种简单的方法可以将这些计数转换为比例?
          • @dsaxton 您可以使用 .value_counts(normalize=True) 将结果转换为比例
          • 要在数据帧上使用它,请将其转换为等效的一维 numpy 数组表示,例如 - pd.value_counts(df.values.ravel()) 它返回一个系列,其 indexvalues 属性包含唯一元素和他们分别计数。
          猜你喜欢
          • 2012-08-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多