【发布时间】:2016-10-18 12:25:18
【问题描述】:
我有一个大约 5400 万行的数据集,我需要从制表符分隔的文本文件中读取,从宽格式转换为长格式,然后写入新的文本文件。数据太大而无法放入内存,所以我一直在使用迭代器。我想将三个单独的变量从宽移到长,所以我一直在使用其中三个单独的迭代器
import pandas as pd
import itertools as it
filename = "C:/example.txt"
iter_a = pd.read_table(filename, iterator=True, usecols=col_list_1, chunksize=100000)
iter_b = pd.read_table(filename, iterator=True, usecols=col_list_2, chunksize=100000)
iter_c = pd.read_table(filename, iterator=True, usecols=col_list_3, chunksize=100000)
所有 usecols 列表都包含一个公共标识符和不同的列。列名基于年份和属性,因此列列表可能如下所示:
col_list_1 = ['Key', 'A90', 'A91', 'A92']
col_list_2 = ['Key', 'B90', 'B91', 'B92']
col_list_3 = ['Key', 'C90', 'C91', 'C92']
并且我想将所有列名更改为没有前导字符/字符的年份,并且仅在年份上融化。
new_colnames = ['Key', '1990', '1991', '1992']
melt_values = ['1990', '1991', '1992']
for achunk, bchunk, cchunk in it.izip(iter_a, iter_b, iter_c):
achunk.columns = new_colnames
bchunk.columns = new_colnames
cchunk.columns = new_colnames
melted_a = pd.melt(achunk, id_vars='Key', value_vars=melt_values, var_name='Year', value_name='A').set_index(['Key', 'Year']).sort_index()
melted_b = pd.melt(bchunk, id_vars='Key', value_vars=melt_values, var_name='Year', value_name='B').set_index(['Key', 'Year']).sort_index()
melted_c = pd.melt(cchunk, id_vars='Key', value_vars=melt_values, var_name='Year', value_name='C').set_index(['Key', 'Year']).sort_index()
join1 = melted_a.join(melted_b, how='outer')
join2 = join1.join(melted_c, how='outer')
join2.dropna(inplace=True, how='all')
join2.to_csv('C:/output_example.txt', sep='\t')
虽然这确实有效,但需要很长时间。我在 15 秒时用 100,000 行块记录了一次迭代。假设它是线性扩展的,我似乎在看 2.25 小时的运行时间。有什么好方法可以加快速度吗?也许使用 numpy 数组或多处理?
【问题讨论】:
-
我们可以假设输入文件都具有相同的键和相同的顺序吗? (否则,分块连接没有多大意义..)另外,你有
value_name='A'三次,这是一个错字吗?数据是数字的吗?缺失数据如何表示? -
@morningsun 所有输入文件都具有相同的键和相同的顺序。
value_name='A'很好,这是一个错字。数据不一定都是数字的。一列总是具有相同的类型,但不同的列可以是数字或字符串。 -
啊,现在我看到你有 3 个迭代器在同一个文件上,有道理。
标签: python performance pandas numpy bigdata