【问题标题】:count the tuples of a pandas Dataframe计算熊猫数据框的元组
【发布时间】:2014-12-26 08:03:44
【问题描述】:

我有以下pandas.DataFrame

      val1 val2 val3 val4
1      7    8    3    2
2      1    4    5    4
3      5    7    5    3
4      7    8    3    2
5      6    8    1    0
6      0    2    5    7
7      1    4    5    4
8      7    8    3    2

我想计算我的 DataFrame 中每个元组的数量。预期结果(或多或少):

count     tuple
3         (7, 8, 3, 2)
2         (1, 4, 5, 4)
1         (5, 7, 5, 3)
1         (6, 8, 1, 0)
1         (0, 2, 5, 7)

还要注意,我真正的 DataFrame 有 数百万个条目,所以我确实需要一些时间优化的解决方案。

直到现在,我的方法是用Series.astype(str) 转换字符串列中的每一列,然后连接这些列,并使用pandas.Series.value_counts()。但我认为可能有一种更快、更自然的方法来解决我的问题。谁能赐教?

【问题讨论】:

    标签: python pandas count tuples


    【解决方案1】:

    我认为自然的解决方案是使用pandas.DataFrame.groupby:

    >>> res = df.groupby(list(df.columns)).size()
    >>> res
    val1  val2  val3  val4
    0     2     5     7       1
    1     4     5     4       2
    5     7     5     3       1
    6     8     1     0       1
    7     8     3     2       3
    dtype: int64
    >>> res.index = [tuple(x) for x in res.index]
    >>> res = res.reset_index().set_index(0)
    >>> res
              index
    0              
    1  (0, 2, 5, 7)
    2  (1, 4, 5, 4)
    1  (5, 7, 5, 3)
    1  (6, 8, 1, 0)
    3  (7, 8, 3, 2)
    

    然后你可以重命名索引和列

    【讨论】:

    • 是的,就是这样!非常感谢您的解决方案!顺便说一句,我不知道谁 -1 我的问题,但我不忽视它..
    • 这太棒了!被困在完全相同的情况下,这救了我的命!它比 value_counts() 快得多!
    【解决方案2】:

    或者你可以做一个简单的groupby:

    df.groupby(['val1', 'val2', 'val3', 'val4']).size()
    
    val1  val2  val3  val4
    0     2     5     7       1
    1     4     5     4       2
    5     7     5     3       1
    6     8     1     0       1
    7     8     3     2       3
    

    如果你必须将它们作为元组:

    pd.DataFrame(df.groupby(['val1', 'val2', 'val3', 'val4']).size(), index=s.index.to_native_types(), columns=['count']).reset_index()
    
              index  count
    0  (0, 2, 5, 7)      1
    1  (1, 4, 5, 4)      2
    2  (5, 7, 5, 3)      1
    3  (6, 8, 1, 0)      1
    4  (7, 8, 3, 2)      3
    

    【讨论】:

    • 不知道to_native_types。这个函数的目的是什么?
    • 我的理解是它类似于tolist(),但也允许控制如何表示NaNs。所以基本上to_native_types可以在上面的代码中替换为tolist。而sgroupby(...).size() 系列。
    【解决方案3】:

    在python中使用Collections.Counter

    from collections import Counter
    
    s = """7    8    3    2
    1    4    5    4
    5    7    5    3
    7    8    3    2
    6    8    1    0
    0    2    5    7
    1    4    5    4
    7    8    3    2"""
    
    In [74]: Counter(s.translate(None, ' ').split())
    Out[74]: Counter({'7832': 3, '1454': 2, '5753': 1, '0257': 1, '6810': 1})
    

    str.translate()None 将通过删除所有空格为您提供数字字符串,然后str.split() 将拆分并在list 中提供单个字符串。

    In [73]: s.translate(None, ' ').split()
    Out[73]: ['7832', '1454', '5753', '7832', '6810', '0257', '1454', '7832']
    

    【讨论】:

    • @user3478208 检查解决方案。
    • 你的 S 是 DataFrame 吗?
    • 谢谢你的回答,但我不太明白你有什么样的s。
    • @user3478208 我不知道 panda 的框架,但 s 是一个字符串,用 Python 的方式你可以像这样解决它。
    • 对不起,我在问题中说这是一个熊猫数据框。无论如何,感谢您的宝贵时间。
    猜你喜欢
    • 2015-01-28
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 2016-05-20
    • 2021-07-22
    相关资源
    最近更新 更多