我是数据分析和python的新手,几乎没有numpy,pytable,pandas等经验。
我正在通过chunk将csv文件读取到数据帧块并将其附加到HDFStore,因为整个数据无法放入内存中。在我的追加操作中,我通过data_columns参数传递数据列表,以便我可以通过HDFStore.select将条件传递给where参数来执行核心外过滤。
是否可以在附加表后指定数据列?
原因是每次写入时,按块附加到HDFStore表执行块的时间会呈指数级增长。我猜测每次使用新数据对HDFStore进行追加时,都会重新计算数据列中的索引。如果将数据完全放在存储中并且在创建后指定数据列以便只计算一次索引,那么效率会更高。
感谢您的想法和帮助。
更新1
以下是我正在运行的代码。请不要我必须清理代码以避免不必要的泄露,并且不提供以下3行代码中的整个列列表,因为有> 100列:
我已确定要从csv中读取dtypes并将其声明为:
csv_dt = {'COL1': dtype('O'), 'TAX': dtype('float64'), 'COL2': dtype('O'), ... }
以下是要写入的表的dtype声明。注意我添加了计算字段'REVENUE',它不在原始csv中。
t_dt = [('COL1', 'S20'), ('COL2', 'S3'), ('COL3', 'f8'), ('TAX', 'f8'), ('REVENUE','f8') ... ]
确定要传递给min_itemsize
的每列的最大字符串长度。这仅适用于dtype('O')
str_len = {'COL1': 3, 'COL2': 3, ...}
以下是分块的代码:
f = HDFStore('FLN2.h5')
for num, chunk in enumerate(read_csv('FLN.csv',dtype=csv_dt, iterator=True, chunksize=250000, parse_dates=True)):
print str(now()),str(num), "Started new chunk"
chunk['MTH'] = to_datetime(chunk.MTH)
chunk.TAX = chunk.TAX.fillna(0)
chunk['REVENUE'] = chunk.NET - chunk.TAX
print str(now()),str(num), "Completed Revenue Calculation"
if num == 0:
f.append('df', chunk, dtype=t_dt, min_itemsize=str_len, dtype=t_dt, data_columns = ['DC1', 'DC2'], expectedrows=42000000)
else:
f.append('df', chunk)
print str(now()),str(num), "Completed writing chunk"
f.flush()
f.flush()
f.close()
昨天,当用于读取csv的chunksize
设置为50000时,此代码运行正常。但是,今天当我尝试运行代码时,我收到以下错误:
Exception: tables cannot write this data -> rows parameter cannot be converted into a recarray object compliant with table '/df/table (Table(0,))
对于我的生活,我无法弄清楚发生了什么。
信息()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 250000 entries, 0 to 249999
Columns: 122 entries, COL1 to REVENUE
dtypes: datetime64[ns](1), float64(40), int64(13), object(68)
请注意,上述内容仅来自写入磁盘的一个块。