【问题标题】:Find most frequent element/row in list of lists在列表列表中查找最频繁的元素/行
【发布时间】:2020-01-10 16:14:26
【问题描述】:

我有一个表格列表:

my_list = [[8, [16, 32], [32, 16, 8], 0],
           [16, [16, 32], [32, 16, 8], 0],
           [16, [32, 64], [32, 16, 8], 0],
           [8, [16, 32], [32, 16, 8], 0]]

我想提取最频繁的项目,即:

most_freq_item = [8, [16, 32], [32, 16, 8], 0]

我尝试将列表转换为 numpy,然后使用 np.unique:

import numpy as np
list_as_np = np.asarray(my_list)
unq, cnt = np.unique(list_as_np, axis=0, return_counts=True)

但这会引发TypeError: The axis argument to unique is not supported for dtype object,因为np.asarray 确实创建了一个对象,而不是一个正确的np.ndarray。

有什么建议吗?非常感谢!

【问题讨论】:

    标签: python-3.x list numpy


    【解决方案1】:

    鉴于主要问题是列表的不可散列属性,这里有一个可能的解决方法:

    >>> import pandas as pd
    >>> my_list = [[8, [16, 32], [32, 16, 8], 0],
               [16, [16, 32], [32, 16, 8], 0],
               [16, [32, 64], [32, 16, 8], 0],
               [8, [16, 32], [32, 16, 8], 0]]
    
    >>> l = [sum([[e] if type(e) == int else e for e in s], []) for s in my_list]
    
    >>> l
    [[8, 16, 32, 32, 16, 8, 0],
     [16, 16, 32, 32, 16, 8, 0],
     [16, 32, 64, 32, 16, 8, 0],
     [8, 16, 32, 32, 16, 8, 0]]
    
    >>> df = pd.DataFrame(l)
    
    >>> result = df.groupby(df.columns.tolist()).size()
    >>> most_freq, cnt = result.idxmax(), result.max()
    
    >>> most_freq
    (8, 16, 32, 32, 16, 8, 0) 
    
    >>> cnt
    2
    

    【讨论】:

      【解决方案2】:

      如果列表的顺序很重要,您可以简单地将子列表转换为字符串并进行比较。

      from collections import Counter
      Counter([str(x) for x in my_list])
      # Counter({'[8, [16, 32], [32, 16, 8], 0]': 2,
      #         '[16, [16, 32], [32, 16, 8], 0]': 1,
      #         '[16, [32, 64], [32, 16, 8], 0]': 1})
      

      当然你也可以使用你的方法,无论哪种方式都会给你一个字符串,你可以从字符串中找到列表

      【讨论】:

        【解决方案3】:

        乔托米:D

        另一种选择是:

        import scipy.stats as ss
        most_frequent, cnt = ss.mode([str(x) for x in my_list])
        
        most_frequent
        array(['[8, [16, 32], [32, 16, 8], 0]'], dtype='<U30')
        
        cnt
        array([2])
        

        【讨论】:

          【解决方案4】:

          使用熊猫

          >>> s = pd.Series(map(str, my_list))
          >>> s.value_counts()
          
          [8, [16, 32], [32, 16, 8], 0]     2
          [16, [32, 64], [32, 16, 8], 0]    1
          [16, [16, 32], [32, 16, 8], 0]    1
          

          获取最频繁的元素:

          s.value_counts().index[0]
          

          【讨论】:

          • 嗨安德烈亚斯!在尝试您的解决方案时,我得到:文件“pandas/_libs/hashtable_func_helper.pxi”,第 348 行,在 pandas._libs.hashtable.value_count_object 文件“pandas/_libs/hashtable_func_helper.pxi”,第 359 行,在 pandas._libs.hashtable .value_count_object TypeError: unhashable type: 'list'
          • @Tommaso Di Noto 我试过了,效果很好。你有什么版本的熊猫?在任何情况下,您都可以将列表映射到字符串:pd.Series(map(str, my_list))
          • 嗨@Andreas,我的熊猫版本是0.25.3
          • 这很奇怪,我有相同的版本,它可以工作。无论如何,我改变了我的答案(这实际上是最初的答案)。现在可以用了吗?
          猜你喜欢
          • 2020-08-20
          • 1970-01-01
          • 2015-10-08
          • 2022-08-16
          • 2021-12-09
          • 1970-01-01
          • 2020-05-13
          • 1970-01-01
          相关资源
          最近更新 更多