已回答:此数据类型似乎不适合添加 任意字符串到hdf5store。
背景
我使用脚本生成单行结果,并以迭代方式将它们附加到磁盘上的文件中。为了加快速度,我决定使用HDF5容器而不是.csv。 A benchmarking然后发现字符串降低了HDF5的速度。我told将字符串转换为categorical
dtype时可以减轻这种情况。
问题
我无法将带有新类别的分类行附加到HDF5。另外,我不知道如何控制cat.codes
的dtypes,AFAIK可以以某种方式完成。
1 - 使用分类数据创建大型数据框
import pandas as pd
import numpy as np
from pandas import HDFStore, DataFrame
import random, string
dummy_data = [''.join(random.sample(string.ascii_uppercase, 5)) for i in range(100000)]
df_big = pd.DataFrame(dummy_data, columns = ['Dummy_Data'])
df_big['Dummy_Data'] = df_big['Dummy_Data'].astype('category')
2 - 创建一行以追加
df_small = pd.DataFrame(['New_category'], columns = ['Dummy_Data'])
df_small['Dummy_Data'] = df_small['Dummy_Data'].astype('category')
3 - 将(1)保存到HDF并尝试追加(2)
df_big.to_hdf('h5_file.h5', \
'symbols_dict', format = "table", data_columns = True, append = False, \
complevel = 9, complib ='blosc')
df_small.to_hdf('h5_file.h5', \
'symbols_dict', format = "table", data_columns = True, append = True, \
complevel = 9, complib ='blosc')
这导致以下异常
ValueError:附加数据[name_axes]的组合无效[name-> Dummy_Data,cname-> Dummy_Data,dtype-> int8,kind-> integer,shape->(1,)] vs当前表 [名称 - > Dummy_Data,cname-> Dummy_Data,dtype-> INT32,kind->整数,形状 - >无]
我的修正尝试次数
我尝试调整cat.catcodes
的dtypes:
df_big['Dummy_Data'] = df_big['Dummy_Data'].cat.codes.astype('int32')
df_small['Dummy_Data'] = df_small['Dummy_Data'].cat.codes.astype('int32')
当我这样做时,错误消失了,但分类dtype也是如此:
df_test = pd.read_hdf('h5_file.h5', key='symbols_dict')
print df_mydict.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100001 entries, 0 to 0 # The appending worked now
Data columns (total 1 columns):
Dummy_Data 100001 non-null int32 # Categorical dtype gone
dtypes: int32(1) # I need to change dtype of cat.codes of categorical
memory usage: 1.1 MB # Not of categorical itself
此外,df_small.info()
首先没有显示cat.codes
的dtype,这使得调试变得困难。我做错了什么?
问题
1。如何正确更改cat.codes
的dtypes?
2.如何在python中正确地将分类数据附加到HDF5?
答案 0 :(得分:3)
如果它对您有帮助,我将重写您的代码的开头。它对我有用。
import pandas as pd
from pandas import HDFStore, DataFrame
import random, string
def create_dummy(nb_iteration):
dummy_data = [''.join(random.sample(string.ascii_uppercase, 5)) for i in range(nb_iteration)]
df = pd.DataFrame(dummy_data, columns = ['Dummy_Data'])
return df
df_small= create_dummy(53)
df_big= create_dummy(100000)
df_big.to_hdf('h5_file.h5', \
'symbols_dict', format = "table", data_columns = True, append = False, \
complevel = 9, complib ='blosc')
df_small.to_hdf('h5_file.h5', \
'symbols_dict', format = "table", data_columns = True, append = True, \
complevel = 9, complib ='blosc')
df_test = pd.read_hdf('test_def.h5', key='table')
df_test
答案 1 :(得分:2)
我不是这方面的专家,但就我至少看过h5py模块http://docs.h5py.org/en/latest/high/dataset.html而言,HDF5支持Numpy数据类型,它不包含任何分类数据类型。
Pandas使用的PyTables相同。
类别数据类型在Pandas datatypes中引入并使用,并描述如下:
分类变量采用有限,通常是固定,可能值的数量(类别; R中的等级)
所以可能每次都要添加一个新类别,你必须以某种方式重新读取hdf5store中的所有现有类别,以便让Pandas重新编制索引吗?
但是,从一般的文档来看,这个数据类型似乎不适合于将任意字符串添加到hdf5store中,除非你确定在添加几个之后就没有新的类别
另外请注意,除非您的应用程序需要极高的性能,否则在SQL中存储数据可能是更好的选择 - 一方面,SQL对字符串有更好的支持。例如,虽然在某些test中发现SQLite比HDF5慢,但它们不包括处理字符串。从CSV跳到HDF5听起来像是从马车跳到火箭,但也许汽车或飞机也能正常工作(或者更好,因为它有更多的选择,可以扩展类比)?