Python 迭代地自动推断大型数据集上的数据类型和最小项大小
在我的工作中,我经常收到一个大的csv文件,其中没有关于内容或格式的任何信息。我正在尝试开发一个工作流来自动推断列的数据类型以及对象数据类型的最大字符串长度,最终目标是将格式化的数据集存储在HDFStore中。我正在寻求帮助,为这个场景提供最佳实践。我有一些有用的东西,但似乎效率很低: 此示例的数据可在此处找到: 前面的代码段为每个块累积推断的数据类型,然后以最大值减少它们:Python 迭代地自动推断大型数据集上的数据类型和最小项大小,python,pandas,hdf5,Python,Pandas,Hdf5,在我的工作中,我经常收到一个大的csv文件,其中没有关于内容或格式的任何信息。我正在尝试开发一个工作流来自动推断列的数据类型以及对象数据类型的最大字符串长度,最终目标是将格式化的数据集存储在HDFStore中。我正在寻求帮助,为这个场景提供最佳实践。我有一些有用的东西,但似乎效率很低: 此示例的数据可在此处找到: 前面的代码段为每个块累积推断的数据类型,然后以最大值减少它们: In[1]:fmts[:10] Out[1]: id int64 f1 int64 f2
In[1]:fmts[:10]
Out[1]:
id int64
f1 int64
f2 int64
f3 float64
f4 int64
f5 int64
f6 int64
f7 float64
f8 float64
f9 float64
dtype: object
第一步就完成了。我已经创建了一个数据类型列表,可以在后续运行中传递给read\u csv
。现在要查找对象
列的最大长度,这些列将作为字符串
存储在HDFStore
中:
# second pass now get max lengths of objects
objs = fmts[fmts == 'object'].index
cnvt = {obj : str for obj in objs}
lens = []
chunker = pd.read_csv('../data/train.csv', chunksize=10000,
converters=cnvt, usecols=objs)
for chunk in chunker:
for col in chunk:
lens.append(chunk.apply(lambda x: max(x.apply(len))))
# reduce the lens into one
lens = dict(reduce(lambda x,y: x.combine(y, max), lens))
我现在有一个字典,其中object类型的列是键,所有块的最大单元格长度是值:
In[2]:lens
Out[2]:
{'f137': 20,
'f138': 26,
'f206': 20,
'f207': 27,
'f276': 20,
'f277': 27,
'f338': 26,
'f390': 32,
'f391': 42,
'f419': 20,
'f420': 26,
'f466': 19,
'f469': 27,
'f472': 35,
'f534': 27,
'f537': 35,
'f626': 32,
'f627': 42,
'f695': 22,
'f698': 22}
最后一步是使用推断的格式和长度将所有内容存储在HDFStore表中:
# Lastly loop through once more to append to an HDFStore table!
store = pd.HDFStore("../data/train.h5")
chunker = pd.read_csv('../data/train.csv', chunksize=10000, dtype=dict(fmts))
for chunk in chunker:
store.append('train', chunk, min_itemsize=lens)
这个工作流程有意义吗?其他人如何处理不适合内存且需要存储在HDFStore磁盘上的大型数据集?只需设置一个您知道不会违反的最大字符串大小,并且只使用浮点类型,“更容易”;那你根本不需要这么做。对于字符串来说效率有点低,但是压缩有帮助。但是我如何确定哪些列是对象呢?我是否仍要进行第一次传递以确定推断的列类型,而忽略第二次传递以计算对象列的长度?如果只传递一个
min\u itemsize=40
(或任何“足够大”的数字),则这将适用于所有对象列,您可以使用:df.dtypes
查看哪些是对象(值是dtype),此外,假设您决定生成的文件大小太大,因为您使用的是非常大的min_itemsize
;写入文件后,请使用另一个例程对其进行后期处理(以创建另一个例程),该例程使用最大列大小。我经常有一个管道的事情要做的hdf文件;有些需要预先知道所有的数据(因此我将其分块并执行我需要的操作),然后在下一步中使用这些信息创建一个新文件并写入。除非你真的需要额外的空间,否则使用压缩和对min_itemsize的合理猜测应该是可行的。我认为我遇到的问题是,通过使用chunksize并写入HDFStore,列数据类型可能会有所不同。在第一个块中看起来像浮点的东西,在下一个块中可能是对象。这就是我所面临的问题,我试图通过提前确定真正的数据类型来克服这个问题。
# Lastly loop through once more to append to an HDFStore table!
store = pd.HDFStore("../data/train.h5")
chunker = pd.read_csv('../data/train.csv', chunksize=10000, dtype=dict(fmts))
for chunk in chunker:
store.append('train', chunk, min_itemsize=lens)