Python:更新频率表(以列表的形式)
我有两个美国州缩写列表(例如): 我想要的结果是这个(基本上是一个有序的频率表): 我的想法是:Python:更新频率表(以列表的形式),python,Python,我有两个美国州缩写列表(例如): 我想要的结果是这个(基本上是一个有序的频率表): 我的想法是: s3=s1+s2 S=[[x,s3.count(x)] for x in set(s3)] 这工作得很好-不过,tbh,我不知道这是非常有效的内存 但是。。。有一个陷阱 s1+s2 …太大,无法保存在内存中,因此我要做的是将s1追加到长度为10K(是的,资源是有限的),然后对其进行汇总(使用上面的列表理解步骤),删除s1的内容,并用下一个数据块重新填充s1(上面仅表示为“s2”,用于演示)。。
s3=s1+s2
S=[[x,s3.count(x)] for x in set(s3)]
这工作得很好-不过,tbh,我不知道这是非常有效的内存
但是。。。有一个陷阱
s1+s2
…太大,无法保存在内存中,因此我要做的是将s1追加到长度为10K(是的,资源是有限的),然后对其进行汇总(使用上面的列表理解步骤),删除s1的内容,并用下一个数据块重新填充s1(上面仅表示为“s2”,用于演示)。。。依此类推,直到循环到达数据的末尾
因此,对于循环的每次迭代,我想将列表的“基本”列表与当前迭代的列表相加。基本上,我的问题是,我如何添加这些:
(当前主数据):
(新数据):
…获取(新的主数据):
…以某种合理有效的方式。如果这是更好地与字典或其他东西,我很好。不幸的是,我不能使用任何远程专用的Python模块——我所要做的就是在封闭、锁定、资源匮乏的Linux环境中使用最精简的Python 2.6版本(工作的危险)。非常感谢您的帮助 您可以使用
itertools.chain
高效地链接两个迭代器:
import itertools
import collections
counts = collections.Counter()
for val in itertools.chain(s1, s2): # memory efficient
counts[val] += 1
一个collections.Counter
对象是一个专门用于计数的dict
。。。如果您知道如何使用dict
,您可以使用集合计数器。但是,它允许您更简洁地将上述内容写成:
counts = collections.Counter(itertools.chain(s1, s2))
另请注意,以下构造:
S=[[x,s3.count(x)] for x in set(s3)]
由于您正在循环中调用s3.count
,因此时间效率也非常低。尽管如此,如果len(set(s3))您可以随心所欲地运行多次,切割数据以适应内存/流式传输,这可能不会太糟糕
import collections
counter = collections.Counter()
counter.update(['foo', 'bar'])
assert counter['foo'] == counter['bar'] == 1
counter.update(['foo', 'bar', 'foo'])
assert counter['foo'] == 3
assert counter['bar'] == 2
assert sorted(counter.items(), key=lambda rec: -rec[1]) == [('foo', 3), ('bar', 2)]
最后一行使用否定计数作为排序键,使较高的计数排在第一位
如果您的计数结构不适合内存,那么您需要一个(基于磁盘的)数据库,如Postgres,或者可能只是一台具有更多内存和更高效键值存储的机器,如Redis。循环是否违背了计数器的目的counts=collections.Counter(itertools.chain(s1,s2))
应该更好。@schwobaseggl是的,最初我使用的是OrderedDict
,因为我认为顺序可能很重要,然后在重新阅读op时改为Counter
,它说“dict很好”。我不确定它是否“违背了目的”,但它肯定不是那么简单。@juanpa.arrivillaga非常感谢-这非常有效!实际上,我在循环中完成了这项工作,就像在第一个示例中一样,因为我需要一直附加到Counter()对象(每次len(s)达到10K)。而且-实际上我确实需要对结果进行排序-所以在循环之后,我只是使用:freqs=sorted(counts.items())转换为一个排序列表(tuple?)--感谢你们两位!谢谢@9000——我也将使用这个解决方案——始终可以使用字典进行更多练习。。。。
S=[['CA',2],['CO',1],['FL',1],['GA',1],['IN',1],['MA',4],['OH',4]]
import itertools
import collections
counts = collections.Counter()
for val in itertools.chain(s1, s2): # memory efficient
counts[val] += 1
counts = collections.Counter(itertools.chain(s1, s2))
S=[[x,s3.count(x)] for x in set(s3)]
it1 = iter(s1)
it2 = iter(s2)
for val in it1:
...
for val in it2:
...
import collections
counter = collections.Counter()
counter.update(['foo', 'bar'])
assert counter['foo'] == counter['bar'] == 1
counter.update(['foo', 'bar', 'foo'])
assert counter['foo'] == 3
assert counter['bar'] == 2
assert sorted(counter.items(), key=lambda rec: -rec[1]) == [('foo', 3), ('bar', 2)]