在Python中并行读取文件
我有一堆文件(差不多100个),里面的数据格式是:
(人数) \t (平均年龄)
这些文件是通过对某个特定人群进行随机走动生成的。每个文件有100,000行,记录了从1到100,000的人口规模的平均年龄。每个文件对应一个发展中国家的不同地方。我们将把这些值与发达国家类似规模地方的平均年龄进行比较。
我想做的是:
for each i (i ranges from 1 to 100,000):
Read in the first 'i' values of average-age
perform some statistics on these values
这意味着,对于每一次运行 i(i的范围是从1到100,000),读取前 i 个平均年龄的值,把它们加到一个列表中,然后进行一些测试(比如Kolmogorov-Smirnov检验或卡方检验)。
为了同时打开所有这些文件,我觉得最好的方法是用一个文件对象的字典。但是我在尝试进行上述操作时遇到了困难。
我的方法在复杂性上是最优的吗?
有没有更好的方法?
3 个回答
0
我不太确定我是否喜欢这种方法,但它可能对你有用。这个方法可能会占用大量内存,但也许能满足你的需求。我假设你的数据文件是按编号排列的。如果不是的话,可能需要做一些调整。
# open the files.
handles = [open('file-%d.txt' % i) for i in range(1, 101)]
# loop for the number of lines.
for line in range(100000):
lines = [fh.readline() for fh in handles]
# Some sort of processing for the list of lines.
这个方法可能接近你需要的效果,但我还是不太确定我喜欢它。如果你的文件行数不一致,这个方法可能会遇到问题。
3
其实,可以在内存中存放1000万行数据。
你可以创建一个字典,字典的键是人数
,值是平均年龄
的列表,每个列表的元素来自不同的文件。也就是说,如果你有100个文件,那么每个列表就会有100个元素。
这样,你就不需要把文件对象存放在dict
里了。
希望这对你有帮助。
1
为什么不采取一个简单的方法呢:
- 依次打开每个文件,读取它的行,把内容放到内存中的一个数据结构里
- 在这个内存中的数据结构上进行统计
下面是一个完整的例子,里面有3个“文件”,每个文件包含3行内容。为了方便,这里用的是StringIO
,而不是实际的文件:
#!/usr/bin/env python
# coding: utf-8
from StringIO import StringIO
# for this example, each "file" has 3 lines instead of 100000
f1 = '1\t10\n2\t11\n3\t12'
f2 = '1\t13\n2\t14\n3\t15'
f3 = '1\t16\n2\t17\n3\t18'
files = [f1, f2, f3]
# data is a list of dictionaries mapping population to average age
# i.e. data[0][10000] contains the average age in location 0 (files[0]) with
# population of 10000.
data = []
for i,filename in enumerate(files):
f = StringIO(filename)
# f = open(filename, 'r')
data.append(dict())
for line in f:
population, average_age = (int(s) for s in line.split('\t'))
data[i][population] = average_age
print data
# gather custom statistics on the data
# i.e. here's how to calculate the average age across all locations where
# population is 2:
num_locations = len(data)
pop2_avg = sum((data[loc][2] for loc in xrange(num_locations)))/num_locations
print 'Average age with population 2 is', pop2_avg, 'years old'
输出结果是:
[{1: 10, 2: 11, 3: 12}, {1: 13, 2: 14, 3: 15}, {1: 16, 2: 17, 3: 18}]
Average age with population 2 is 14 years old