- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在处理一个巨大的数据集(数百 GB),其中约有 4000 万个标识符存储为 32 个字符的字符串,每个标识符都有数百或数千行数字数据。
为了节省空间并提高从磁盘读取数据的效率,似乎最好不要不在数据集中一遍又一遍地重复标识符。比如一张数据表,看起来像
verylongstringidentifier1, 1.2
verylongstringidentifier1, 2.3
verylongstringidentifier1, 3.4
.
.
verylongstringidentifier2, 2.1
verylongstringidentifier2, 1.0
.
.
如果字符串标识符不重复,则可以更有效地存储。一种选择是为每个标识符保存单独的文件,我可能会走这条路,但拥有数百万个单独的小文件有点烦人,而且从磁盘 I/O 的角度来看可能效率低下。
我对 hdf5 完全陌生,但我读到的内容表明它应该适用于这种情况,因为数据集可以使用标识符作为键来存储。但是,当我保存到一个 hdf5 文件时,生成的文件大约比我简单地写入一个平面 csv 文件时得到的文件大 40 倍。我是否遗漏了有关 hdf5 文件存储方式的信息,或者我只是做错了什么?下面的测试代码是我用来验证(并尝试诊断)问题的代码。
# trying to figure out why hdf5 file sizes are so huge
import time
import string
import random
import numpy as np
import pandas as pd
from pandas import HDFStore
# generate 1000 random 32-character strings
strings = [''.join(random.choices(string.ascii_lowercase, k=32)) for _ in range(1000)]
# for each of these random strings, create 200 rows of three random floats
# concatenate into one big dataframe
df = pd.DataFrame()
for s in strings:
vars = np.random.rand(200,3)
ss = np.full((200,1),s)
s_data = np.concatenate((ss, vars), axis=1)
df = pd.concat([df, pd.DataFrame(s_data)], axis=0)
df.columns = ['string', 'v1', 'v2', 'v3']
# write to one big csv file
df.to_csv('/tmp/test.csv', index=False)
# write to compressed bzip2 file
df.to_csv('/tmp/test.csv.bz2', index=False, compression='bz2')
# write to separate csv files for each string
unique_strings = df.string.unique()
for s in unique_strings:
s_chunk = df[df.string == s]
fname = '/tmp/test_' + s + '.csv.bz2'
# don't need to store the string, since it can be retrieved as the filename
s_chunk[['v1', 'v2', 'v3']].to_csv(fname, index=False, compression='bz2')
# write to hdf5 file with strings as keys
# what I'm trying to do here is *not* save the strings in the datasets, but instead
# use the strings as the names (keys) for the datasets
# My understanding is this would enable me to retrieve the data for a given string
# with pd.read_hdf(h5data, key=<string for which I want data>)
h5data = HDFStore('/tmp/test.h5')
for s in unique_strings:
s_chunk = df[df.string == s]
# don't need to store the string, because we'll use it as the key
s_chunk[['v1', 'v2', 'v3']].to_hdf(h5data, key=s, format='table', complib='bzip2')
h5data.close()
生成的文件大小:
18M /tmp/test.csv
4.7M /tmp/test.csv.bz2
80M /tmp/test.h5
最佳答案
发生这种情况的原因可能是 Pandas 将每个组/数据集的大量无关信息转储到 HDF5 文件中。当我运行您的代码并使用 HDFView 检查文件时, 这很明显。
我更喜欢使用 h5py用于创建和管理 HDF5 文件的库,因为它允许更加简单和控制。
我尝试使用 h5py 构建文件,其中每个组都被命名为一个唯一的字符串,并且在每个组内是 DataFrame 的每一列的数据集。我在您的脚本中使用了以下内容来写入 HDF5:
with h5py.File("/tmp/test.h5", "w") as h5data:
for s in unique_strings:
s_chunk = df[df.string == s]
# create group with name = string
g = h5data.create_group(s)
# create datasets within group for each data column
dset_v1 = g.create_dataset("v1", data=s_chunk["v1"].values.astype(np.float32), compression="gzip")
dset_v2 = g.create_dataset("v2", data=s_chunk["v2"].values.astype(np.float32), compression="gzip")
dset_v3 = g.create_dataset("v3", data=s_chunk["v3"].values.astype(np.float32), compression="gzip")
结果(注意我使用的是 gzip
而不是 bz2
):
18M /tmp/test.csv
5.2M /tmp/test.csv.bz2
11M /tmp/test.h5
进一步的优化是在每个组中只有一个数据集,该数据集是一个二维数组。在这种情况下,三个 create_dataset
调用将被一个替换:
dset = g.create_dataset("data", data=s_chunk[["v1", "v2", "v3"]].values.astype(np.float32), compression="gzip")
结果:
18M /tmp/test.csv
5.0M /tmp/test.csv.bz2
6.0M /tmp/test.h5
使用 bz2
作为压缩会进一步缩小。
关于python - 为什么我的 hdf5 文件看起来太大了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65119241/
只是想知道我对组/数据集名称的自由程度如何,或者是否需要使名称简短(因此可读性较差)。这适用于包含许多具有许多重复名称的组和数据集的 HDF5 文件。一些 XML API 做 string inter
简短问题 当 Pandas 在 HDFStore 上工作时(例如: .mean() 或 .apply() ),它是否将内存中的完整数据作为 DataFrame 加载,还是将记录作为 Serie 进行处
我有几个不同的相关数据框(如果需要,可以使用 id 加入它们)。但是,我并不总是同时需要它们。 由于它们非常大,将它们存储在单独的 HDF 存储中是否有意义?或者当我处理同一文件中的其他帧时,携带“未
我似乎无法让它发挥作用。所有示例和线程都让人创建新的数据集。我只想更新已创建的数据集中的一个字段。 这是我所拥有的: h5_file = h5py.File(event_file_path, "r+"
我在 hadoop 上写入小文件时遇到一个奇怪的问题。下面是示例程序 public void writeFile(Configuration conf, String message, String
当我运行 hdf namenode -format 时,它想要删除目录 /home/hadoop/hadooptmpdata/dfs/name/current 但它没有权限执行此操作。如何授予它权限?
有没有办法使用 pandas HDF 存储获取 HDF 表的信息? 例如在 SQL 中有: SELECT COUNT(*) 我想阅读基本表格大小而不必自己加载表格。 最佳答案 试试这个: In [4]
在 pandas 下,每次我使用表格格式而不是固定格式时,我的内存消耗都会爆炸。 import numpy as np np.random.seed(seed=10) df = pd.DataFram
我正在处理大量数据集,每个数据集都是一个 pandas DataFrame,由于它们的大小,我需要从磁盘访问它们。从我读到的内容来看,HDF 似乎是与它们一起工作的好方法,但我对构建数据的最佳方法有点
我正在开发云服务器,我需要使用 blob 存储来存储 HDF 文件 ( http://www.hdfgroup.org/HDF5/ )。 与文件中的创建、读取、写入和修改数据元素相关的函数来自 HDF
我正在尝试将数据存储为 hdf 格式,并希望将默认数据类型设置为表,以便稍后查询。 我正在使用基本代码: import pandas as pd from numpy import random as
我最近在 Lubuntu 上安装了 Anacondas Python。 我正在尝试加载可在 Windows PC 上运行的 HDF 文件: In [14]: import pandas as pd I
我写了下面的脚本,但是我有一个内存消耗的问题,pandas 分配了超过 30 G 的内存,其中数据文件的总和大约是 18 G import pandas as pd import numpy as n
您好,我看到了一些以 HDF5 格式存储的科学数据,我想知道是否有任何 NoSQl 解决方案可以达到与 HDF5 相同的读/写性能。 我的示例的数据使用树结构(/root 然后/root/key 然后
我想知道如何获取 hdf 文件的列名(似乎存储在 hdf header 中);例如,一个文件可能有名为 [a,b,c,d] 的列,而另一个文件有 [a,b,c] 列,而另一个文件有 [b,e,r,z]
我想做什么? pd.read_csv(... nrows=###) 可以读取文件的前 n 行。我想在使用 pd.read_hdf(...) 时做同样的事情。 问题是什么? 我对 documentati
我想将数千张动物图像加载到 pandas df 中,添加特征并可能转换为 HDF。 我使用 cv2.imread() 尝试了以下方法 import cv2 import os import numpy
我想知道 HDF 套件中嵌入的 kafka 和 Confluence 套件中嵌入的 kafka 之间的差异,特别是模式注册工具。 最佳答案 https://registry-project.readt
我想知道 HDF 套件中嵌入的 kafka 和 Confluence 套件中嵌入的 kafka 之间的差异,特别是模式注册工具。 最佳答案 https://registry-project.readt
我使用 pandas 和 hdf5 文件来处理大量数据(例如 10GB 或更多)。我想使用表格格式,以便在读取数据时能够有效地查询数据。但是,当我想将数据写入 hdf 存储时(使用 DataFrame
我是一名优秀的程序员,十分优秀!