2016-11-15 73 views
0

的名单我有一个列表:频率元组

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 

,并做一些循环过它,但我得到的错误是:

unhashable类型:列表

+0

尝试:在'计数器(元组(i)用于I A [ 0])'因为你有一个带有第一个元组元组的列表,其中存在需要被转换为元组的列表 –

+0

@ Mr.A耶,工作正常,谢谢,请你看看我编辑过的对问题 – Shubham

+0

@Mr。 A考虑条目如 ['7','8']和['8','7'] 相同(重复)。并且唯一一个条目应该在列中并且频率应该被添加到该列中。 – Shubham

回答

1

尝试:

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 
+0

先生,它会删除我的副本吗?例如[7,8]和[8,7]是相同的,并从列表中删除[8,7],但频率添加[7,8] – Shubham

+0

是的,这将删除重复 –

+0

谢谢先生,它只是一部分我的代码,如果你能帮我解决这个问题,这将是非常有用的 [点击链接](http://stackoverflow.com/questions/40594210/create-a-bigram-from-a-column- in-pandas-df) – Shubham

3

名单不是可哈希要用作字典键,您需要将它们转换为可哈希对象。在这种情况下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)] 

如果你要考虑unordere数组你有相同的对它们进行排序它们将它们传递到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}) 

注意,由于你的数字是字符串,如果他们有一个以上的数字长度,你应该在排序前将它们转换为整数,否则它们会按照字典顺序排序。 a = [('7', '8'), ... ('4', '7')]

或者您可以将列表映射到元组,因为元组是可哈希而不是名单:

+0

考虑类似于 ['7','8']和['8','7'] 相同(重复)。并且唯一一个条目应该在列中并且频率应该被添加到该列中。 – Shubham

+0

感谢先生,这只是我的代码的一部分,如果你能帮我解决这个问题,这将是非常有用的 [点击链接](http://stackoverflow.com/questions/40594210/create-一个bigram-from-a-column-in-pandas-df) – Shubham

+0

可能没必要首先将它们转换为整数,因为'sorted'函数是一致的,无关紧要我们对'['3'只有在保证一致性的前提下,'1','2']到'['1','2','3']或'['1','3','2']' ,最终输出中不存在重复项。 – Jason

2

,如果你改变你的列表,将工作中使用计数器。

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

+0

考虑类似于 ['7','8']和['8','7'] 相同(重复)。并且唯一一个条目应该在列中并且频率应该被添加到该列中。 – Shubham

+0

查看更新。 @SRingne – Jason

+0

先生,它会删除重复的条目,如我所说的? – Shubham

0

我想你可以使用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)] 

如果在列表中两个以上的项目,可以考虑使用分类为关键。这可能不是有效的,但可以方便

[(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)] 
+0

先生,它会删除我的副本吗?例如[7,8]和[8,7]是相同的,并从列表中删除[8,7],但在[7,8]中添加频率 – Shubham

+0

@SRingne:是的。看我上面的例子 – Abhijit

+0

谢谢,先生,这只是我的代码的一部分,如果你能帮我解决这个问题,这将是非常有用的 [点击链接](http://stackoverflow.com/questions/ 40594210 /创建一个bigram-from-a-column-in-pandas-df) – Shubham