【问题标题】:Frequency of a list of tuples元组列表的频率
【发布时间】:2017-03-28 22:54:52
【问题描述】:

我有一个清单:

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],...............['3','4'])]

我想创建 2 列来给出列表中元组的频率。例如:

bigram      frequency
['7','8']     2
['4','7']     3
['3', '4']    6

等等。

另外,考虑像 ['7','8']['8','7'] 这样的条目相同(重复)。列中应该只有一个条目,并且应该添加频率。

我正在尝试使用

from collections import counter

并对其进行一些循环,但我收到以下错误:

不可散列的类型:列表

【问题讨论】:

  • 尝试:Counter(tuple(i) for i in a[0]),因为您有一个包含第一个元素元组的列表,其中存在需要转换为元组的列表
  • @Mr.A 是的,工作正常,谢谢,你能看看我对这个问题所做的编辑
  • @Mr.A 认为 ['7','8'] 和 ['8','7'] 等条目相同(重复)。并且只有一个条目应该在列中,并且应该添加频率。

标签: python python-3.x


【解决方案1】:

我猜你可以使用itertools.groupby 对排序后的项目列表进行分组。组的键可以是可以创建有序列表的自定义键。对于二进制元组,可以使用简单的比较来创建这样的元组

考虑

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],['4','3'])]


from itertools import groupby
key = lambda tup: tup if tup[0] < tup[1] else tup[::-1]
[(key,  len(list(values))) 
 for key, values in groupby(sorted(a[0], key = key), key = key)]
Out[42]: 
[(['3', '4'], 2),
 (['3', '8'], 1),
 (['4', '7'], 1),
 (['4', '8'], 1),
 (['7', '8'], 1)]

如果列表中有两个以上的项目,请考虑使用 sorted 作为键。这可能效率不高,但很方便

[(key,  len(list(values)))
 for key, values in groupby(sorted(a[0], key = sorted), key = sorted)]
Out[37]: 
[(['3', '4'], 2),
 (['3', '8'], 1),
 (['4', '7'], 1),
 (['4', '8'], 1),
 (['7', '8'], 1)]

【讨论】:

  • 先生,它会删除我的重复项吗?例如 [7,8] 和 [8,7] 相同,从列表中删除 [8,7] 但在 [7,8] 中添加频率
  • @SRingne:是的。看我上面的例子
  • 谢谢先生,这只是我代码的一部分,如果你能帮助我解决这个问题,那将非常有帮助click the link
【解决方案2】:

列表不能作为字典键使用,您需要将它们转换为可散列对象。在这种情况下,tuple 是一个合适的选择:

In [5]: Counter(map(tuple, a[0])).items()
Out[5]: 
[(('4', '7'), 1),
 (('4', '8'), 1),
 (('7', '8'), 1),
 (('3', '4'), 2),
 (('3', '8'), 1)]

如果您想考虑相同的无序数组,您必须对它们进行排序,将它们传递给Counter

In [7]: a
Out[7]: 
[(['7', '8'],
  ['4', '7'],
  ['3', '4'],
  ['3', '8'],
  ['4', '8'],
  ['3', '4'],
  ['7', '4'])]

In [8]: Counter(tuple(sorted(i)) for i in a[0])
Out[8]: Counter({('4', '7'): 2, ('3', '4'): 2, ('3', '8'): 1, ('7', '8'): 1, ('4', '8'): 1})

注意,由于您的数字是字符串,如果它们的长度超过一位,您应该在排序之前将它们转换为整数,否则它们将按字典顺序排序。

【讨论】:

  • 考虑像 ['7','8'] 和 ['8','7'] 一样的条目(重复)。并且只有一个条目应该在列中,并且应该添加频率。
  • 谢谢先生,这只是我代码的一部分,如果你能帮助我解决这个问题,那将非常有帮助click the link
  • 可能不需要先将它们转换为整数,因为sorted函数是一致的,我们将['3', '1', '2']排序为['1', '2', '3']['1', '3', '2']都没有关系,只有当可以保证一致性,最终输出不会有重复。
【解决方案3】:

试试这个:

from collections import Counter

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],['3','4'],['7','8'],['8','7'],['4','3'])]

frequency_list = Counter(tuple(sorted(i)) for i in a[0])

print "bigram","frequency"
for key,val in frequency_list.items():
    print key, val

输出如下

bigram    frequency
('4', '7') 1
('4', '8') 1
('7', '8') 3
('3', '4') 3
('3', '8') 1

【讨论】:

  • 先生,它会删除我的重复项吗?例如 [7,8] 和 [8,7] 相同,从列表中删除 [8,7] 但在 [7,8] 中添加频率
  • 谢谢先生,这只是我代码的一部分,如果你能帮助我解决这个问题,那将非常有帮助click the link
  • 我得到的输出,我可以将它存储在熊猫数据框中吗?
【解决方案4】:

如果您将列表更改为: a = [('7', '8'), ... ('4', '7')]

或者您可以将列表映射到元组,因为元组是可散列的,但不是列表。

[更新] 先排序,然后将每个列表映射到元组。 Counter(map(lambda x: tuple(sorted(x)), a[0])).items()(基于@Kasramvd)。

【讨论】:

  • 考虑像 ['7','8'] 和 ['8','7'] 一样的条目(重复)。并且只有一个条目应该在列中,并且应该添加频率。
  • 先生,它会像我提到的那样删除重复的条目吗?
  • 会的。你可以试试 :) sorted 函数会列出 ['8', '7'] 到 ['7', '8'] 和 tuple(['7', '8']) 会得到('7','8')。 @SRingne
  • 谢谢,这只是我代码的一部分,如果你能帮助我解决这个问题,那将非常有帮助click the link
猜你喜欢
  • 2018-05-30
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 2017-12-18
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多