pandas 数据框中大型字符串列的高效存储
Efficient storage of large string column in pandas dataframe
我有一个很大的 pandas 数据框,其中的字符串列在字符串大小上存在高度偏差。大多数行的字符串长度 < 20,但也有一些行的字符串长度超过 2000。
我使用 pandas.HDFStorage.append 将此数据帧存储在磁盘上并设置 min_itemsize = 4000。但是,这种方法效率非常低,因为 hdf5 文件非常大,而且我们知道大多数其中是空的。
是否可以为这个字符串列的行分配不同的大小?即给字符串短的行赋值smallmin_itemsize,给string长的行赋值largemin_itemsize。
当使用HDFStore
存储字符串时,列中字符串的最大长度是该特定列的宽度,可以自定义,参见here。
有几个选项可用于处理各种情况。压缩有很大帮助。
In [6]: df = DataFrame({'A' : ['too']*10000})
In [7]: df.iloc[-1] = 'A'*4000
In [8]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10000 entries, 0 to 9999
Data columns (total 1 columns):
A 10000 non-null object
dtypes: object(1)
memory usage: 156.2+ KB
这些是固定存储,字符串存储为object
类型,所以性能不是特别好;这些商店也不可用于查询/追加。
In [9]: df.to_hdf('test_no_compression_fixed.h5','df',mode='w',format='fixed')
In [10]: df.to_hdf('test_no_compression_table.h5','df',mode='w',format='table')
Table 存储非常灵活,但强制存储大小固定。
In [11]: df.to_hdf('test_compression_fixed.h5','df',mode='w',format='fixed',complib='blosc')
In [12]: df.to_hdf('test_compression_table.h5','df',mode='w',format='table',complib='blosc')
通常使用分类表示提供 运行-时间和存储效率。
In [13]: df['A'] = df['A'].astype('category')
In [14]: df.to_hdf('test_categorical_table.h5','df',mode='w',format='table')
In [15]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10000 entries, 0 to 9999
Data columns (total 1 columns):
A 10000 non-null category
dtypes: category(1)
memory usage: 87.9 KB
In [18]: ls -ltr *.h5
-rw-rw-r-- 1162080 Aug 31 06:36 test_no_compression_fixed.h5
-rw-rw-r-- 1088361 Aug 31 06:39 test_compression_fixed.h5
-rw-rw-r-- 40179679 Aug 31 06:36 test_no_compression_table.h5
-rw-rw-r-- 259058 Aug 31 06:39 test_compression_table.h5
-rw-rw-r-- 339281 Aug 31 06:37 test_categorical_table.h5
我有一个很大的 pandas 数据框,其中的字符串列在字符串大小上存在高度偏差。大多数行的字符串长度 < 20,但也有一些行的字符串长度超过 2000。
我使用 pandas.HDFStorage.append 将此数据帧存储在磁盘上并设置 min_itemsize = 4000。但是,这种方法效率非常低,因为 hdf5 文件非常大,而且我们知道大多数其中是空的。
是否可以为这个字符串列的行分配不同的大小?即给字符串短的行赋值smallmin_itemsize,给string长的行赋值largemin_itemsize。
当使用HDFStore
存储字符串时,列中字符串的最大长度是该特定列的宽度,可以自定义,参见here。
有几个选项可用于处理各种情况。压缩有很大帮助。
In [6]: df = DataFrame({'A' : ['too']*10000})
In [7]: df.iloc[-1] = 'A'*4000
In [8]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10000 entries, 0 to 9999
Data columns (total 1 columns):
A 10000 non-null object
dtypes: object(1)
memory usage: 156.2+ KB
这些是固定存储,字符串存储为object
类型,所以性能不是特别好;这些商店也不可用于查询/追加。
In [9]: df.to_hdf('test_no_compression_fixed.h5','df',mode='w',format='fixed')
In [10]: df.to_hdf('test_no_compression_table.h5','df',mode='w',format='table')
Table 存储非常灵活,但强制存储大小固定。
In [11]: df.to_hdf('test_compression_fixed.h5','df',mode='w',format='fixed',complib='blosc')
In [12]: df.to_hdf('test_compression_table.h5','df',mode='w',format='table',complib='blosc')
通常使用分类表示提供 运行-时间和存储效率。
In [13]: df['A'] = df['A'].astype('category')
In [14]: df.to_hdf('test_categorical_table.h5','df',mode='w',format='table')
In [15]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10000 entries, 0 to 9999
Data columns (total 1 columns):
A 10000 non-null category
dtypes: category(1)
memory usage: 87.9 KB
In [18]: ls -ltr *.h5
-rw-rw-r-- 1162080 Aug 31 06:36 test_no_compression_fixed.h5
-rw-rw-r-- 1088361 Aug 31 06:39 test_compression_fixed.h5
-rw-rw-r-- 40179679 Aug 31 06:36 test_no_compression_table.h5
-rw-rw-r-- 259058 Aug 31 06:39 test_compression_table.h5
-rw-rw-r-- 339281 Aug 31 06:37 test_categorical_table.h5