【问题标题】:python equivalent of R table相当于R表的python
【发布时间】:2014-10-31 21:11:10
【问题描述】:

我有一个清单

[[12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [6, 0], [12, 6], [0, 6], [12, 0], [0, 6], [0, 6], [12, 0], [0, 6], [6, 0], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [0, 6], [0, 6], [12, 6], [6, 0], [6, 0], [12, 6], [12, 0], [12, 0], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 0], [12, 0], [12, 0], [12, 0], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [12, 6], [12, 0], [0, 6], [6, 0], [12, 0], [0, 6], [12, 6], [12, 6], [0, 6], [12, 0], [6, 0], [6, 0], [12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [12, 0], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [0, 6], [12, 0], [12, 6], [0, 6], [0, 6], [12, 0], [0, 6], [12, 6], [6, 0], [12, 6], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [12, 6], [12, 0], [6, 0], [12, 6], [6, 0], [12, 0], [6, 0], [12, 0], [6, 0], [6, 0]]

我想计算这个列表中每个元素的频率。 像

freq[[12,6]] = 40

在 R 中,这可以通过 table 函数获得。 python3有类似的吗?

【问题讨论】:

标签: python r frequency


【解决方案1】:

Pandas 有一个名为 value_counts() 的内置函数。

示例:如果您的 DataFrame 有一个值为 0 和 1 的列,并且您想计算每个列的总频率,那么只需使用这个:

df.colName.value_counts()

【讨论】:

  • 这应该是最佳答案。
  • value_counts 是类“pandas.Series”的方法,而不是pandas.DataFrame。与 R 表函数不同,它仅从列计数,而不是数据帧。
  • 谢谢!我忘了向下滚动;我以前赞成这个答案,但我忘了!
  • 使用df.colName.value_counts(dropna=False) 包含NaN(缺失值计数)。
【解决方案2】:

collections 库中的 Counter 对象将像这样运行。

from collections import Counter

x = [[12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [6, 0], [12, 6], [0, 6], [12, 0], [0, 6], [0, 6], [12, 0], [0, 6], [6, 0], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [0, 6], [0, 6], [12, 6], [6, 0], [6, 0], [12, 6], [12, 0], [12, 0], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 0], [12, 0], [12, 0], [12, 0], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [12, 6], [12, 0], [0, 6], [6, 0], [12, 0], [0, 6], [12, 6], [12, 6], [0, 6], [12, 0], [6, 0], [6, 0], [12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [12, 0], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [0, 6], [12, 0], [12, 6], [0, 6], [0, 6], [12, 0], [0, 6], [12, 6], [6, 0], [12, 6], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [12, 6], [12, 0], [6, 0], [12, 6], [6, 0], [12, 0], [6, 0], [12, 0], [6, 0], [6, 0]]

# Since the elements passed to a `Counter` must be hashable, we have to change the lists to tuples.
x = [tuple(element) for element in x]

freq = Counter(x)

print freq[(12,6)]

# Result:  28

【讨论】:

    【解决方案3】:

    假设您无论如何都需要将数据转换为pandas DataFrame,这样您就有了

    L = [[12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [6, 0], [12, 6], [0, 6], [12, 0], [0, 6], [0, 6], [12, 0], [0, 6], [6, 0], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [0, 6], [0, 6], [12, 6], [6, 0], [6, 0], [12, 6], [12, 0], [12, 0], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 0], [12, 0], [12, 0], [12, 0], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [12, 6], [12, 0], [0, 6], [6, 0], [12, 0], [0, 6], [12, 6], [12, 6], [0, 6], [12, 0], [6, 0], [6, 0], [12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [12, 0], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [0, 6], [12, 0], [12, 6], [0, 6], [0, 6], [12, 0], [0, 6], [12, 6], [6, 0], [12, 6], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [12, 6], [12, 0], [6, 0], [12, 6], [6, 0], [12, 0], [6, 0], [12, 0], [6, 0], [6, 0]]
    df = pd.DataFrame(L, columns=('a', 'b'))
    

    然后您可以按照this answer 中的建议使用groupby.size()

    tab = df.groupby(['a', 'b']).size()
    

    tab 如下所示:

    In [5]: tab
    Out[5]:
    a   b
    0   6    19
    6   0    20
    12  0    33
        6    28
    dtype: int64
    

    并且可以使用unstack()轻松更改为表格形式:

    In [6]: tab.unstack()
    Out[6]:
    b      0     6
    a
    0    NaN  19.0
    6   20.0   NaN
    12  33.0  28.0
    

    Fill NaNsconvert to int 随意!

    【讨论】:

    • 这在功能上等同于 R table 函数。
    • 正是我想要的。
    • 我尝试在 groupby() 中使用 dropna = False 来包含 NaN,但它不起作用。 NaN 怎么能包含在表格中?
    • @Ankhnesmerira 你能提供一个失败的例子吗?在L 中插入float("nan") 并使用df.groupby(['a', 'b'], dropna=False).size() 在我的机器上工作正常(tm):-)
    【解决方案4】:
    import pandas
    x = [[12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [6, 0], [12, 6], [0, 6], [12, 0], [0, 6], [0, 6], [12, 0], [0, 6], [6, 0], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [0, 6], [0, 6], [12, 6], [6, 0], [6, 0], [12, 6], [12, 0], [12, 0], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 0], [12, 0], [12, 0], [12, 0], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [12, 6], [12, 0], [0, 6], [6, 0], [12, 0], [0, 6], [12, 6], [12, 6], [0, 6], [12, 0], [6, 0], [6, 0], [12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [12, 0], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [0, 6], [12, 0], [12, 6], [0, 6], [0, 6], [12, 0], [0, 6], [12, 6], [6, 0], [12, 6], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [12, 6], [12, 0], [6, 0], [12, 6], [6, 0], [12, 0], [6, 0], [12, 0], [6, 0], [6, 0]] 
    ps = pandas.Series([tuple(i) for i in x])
    counts = ps.value_counts()
    print counts
    

    你会得到如下结果:

    (12, 0)    33
    (12, 6)    28
    (6, 0)     20
    (0, 6)     19
    

    对于[(12,6)],您将得到准确的数字,这里是28

    更多关于pandas,这是一个强大的Python数据分析工具包,你可以阅读官方文档:http://pandas.pydata.org/pandas-docs/stable/

    更新:

    如果顺序无关紧要,只需使用 sorted: ps = pandas.Series([tuple(sorted(i)) for i in x]) 之后的结果是:

    (0, 6)     39
    (0, 12)    33
    (6, 12)    28
    

    【讨论】:

    • 熊猫有没有一种简单的方法来考虑元素的相等排列? [12,0] = [0,12] ?
    • @Donbeo 查看更新。排序应该是最简单的方法;-)
    • 如果您接受删除重复项,则设置是可以的。只要你不关心 [0,1,1] 和 [0,1] 之间的区别,使用 set 就可以了。
    • 使用df.colName.value_counts(dropna=False) 包含NaN(缺失值计数)。
    【解决方案5】:

    恕我直言,pandas 为这个“制表”问题提供了更好的解决方案:

    一维:

    my_tab = pd.crosstab(index = df["feature_you_r_interested_in"],
                                  columns="count")
    

    比例计数:

    my_tab/my_tab.sum()
    

    二维(有总计):

    cross = pd.crosstab(index=df["feat1"], 
                                 columns=df["feat2"],
                                 margins=True)
    
    cross
    

    另外,正如其他同事所提到的,pandas value_counts 方法可能就是你所需要的。太好了,如果你愿意,你可以用百分比来计算:

    df['your feature'].value_counts(normalize=True)
    

    我非常感谢这个博客:

    http://hamelg.blogspot.com.br/2015/11/python-for-data-analysis-part-19_17.html

    【讨论】:

    • 链接失效。这个可以:hamelg.blogspot.com/2015/11/…
    • 感谢您的第一个解决方案!顺便说一句,您可以在交叉表中使用参数normalize='columns' 来获取比例计数。
    【解决方案6】:

    在 Numpy 中,我发现最好的方法是使用 unique,例如:

    import numpy as np
    
    # OPs data
    arr = np.array([[12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [6, 0], [12, 6], [0, 6], [12, 0], [0, 6], [0, 6], [12, 0], [0, 6], [6, 0], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [0, 6], [0, 6], [12, 6], [6, 0], [6, 0], [12, 6], [12, 0], [12, 0], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 0], [12, 0], [12, 0], [12, 0], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [12, 6], [12, 0], [0, 6], [6, 0], [12, 0], [0, 6], [12, 6], [12, 6], [0, 6], [12, 0], [6, 0], [6, 0], [12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [12, 0], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [0, 6], [12, 0], [12, 6], [0, 6], [0, 6], [12, 0], [0, 6], [12, 6], [6, 0], [12, 6], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [12, 6], [12, 0], [6, 0], [12, 6], [6, 0], [12, 0], [6, 0], [12, 0], [6, 0], [6, 0]])
    
    values, counts = np.unique(arr, axis=0, return_counts=True)
    
    # into a dict for presentation
    {tuple(a):b for a,b in zip(values, counts)}
    

    给我:{(0, 6): 19, (6, 0): 20, (12, 0): 33, (12, 6): 28} 与其他答案匹配

    这个例子比我通常看到的要复杂一些,因此需要axis=0 选项,如果你只想在任何地方都有唯一值,你可以忽略它:

    # generate random values
    x = np.random.negative_binomial(10, 10/(6+10), 100000)
    
    # get table
    values, counts = np.unique(x, return_counts=True)
    
    # plot
    import matplotlib.pyplot as plt
    plt.vlines(values, 0, counts, lw=2)
    

    R 似乎让这种事情变得更方便了!上面的 Python 代码就是plot(table(rnbinom(100000, 10, mu=6)))

    【讨论】:

      【解决方案7】:

      您可能可以使用列表理解进行一维计数。

      L = [[12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [6, 0], [12, 6], [0, 6], [12, 0], [0, 6], [0, 6], [12, 0], [0, 6], [6, 0], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [0, 6], [0, 6], [12, 6], [6, 0], [6, 0], [12, 6], [12, 0], [12, 0], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 0], [12, 0], [12, 0], [12, 0], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [0, 6], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [12, 6], [12, 0], [0, 6], [6, 0], [12, 0], [0, 6], [12, 6], [12, 6], [0, 6], [12, 0], [6, 0], [6, 0], [12, 6], [12, 0], [0, 6], [12, 0], [12, 0], [12, 0], [6, 0], [12, 6], [12, 6], [12, 6], [12, 6], [0, 6], [12, 0], [12, 6], [0, 6], [0, 6], [12, 0], [0, 6], [12, 6], [6, 0], [12, 6], [12, 6], [12, 0], [12, 0], [12, 6], [0, 6], [6, 0], [12, 0], [6, 0], [12, 0], [12, 0], [12, 6], [12, 0], [6, 0], [12, 6], [6, 0], [12, 0], [6, 0], [12, 0], [6, 0], [6, 0]]
      countey = [tuple(x) for x in L]
      freq = {x:countey.count(x) for x in set(countey)}
      
      In [2]: %timeit {x:countey.count(x) for x in set(countey)}
              100000 loops, best of 3: 15.2 µs per loop   
      
      In [4]: print(freq)
      Out[4]: {(0, 6): 19, (6, 0): 20, (12, 0): 33, (12, 6): 28}
      
      In [5]: print(freq[(12,6)])
      Out[5]: 28
      

      【讨论】:

        猜你喜欢
        • 2018-06-23
        • 2011-06-25
        • 2017-09-10
        • 2016-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-25
        • 2019-07-14
        相关资源
        最近更新 更多