HDFStore 获取列名
HDFStore get column names
我有一些问题 pandas' HDFStore
太慢了,不幸的是我无法从这里的其他问题中找到令人满意的解决方案。
情况
我有一个大 DataFrame,主要包含浮点数,有时包含整数列,这些列经过多个处理步骤(重命名、删除错误条目、按 30 分钟聚合)。每行都有一个与之关联的时间戳。我想将一些中间步骤保存到HDF文件中,以便用户可以迭代地执行单个步骤而无需每次都从头开始。
此外,用户应该能够从这些保存中绘制某些列,以便 select 坏数据。因此我只想检索列名而不读取 HDFStore 中的数据。
具体来说,用户应该获得存储在 HDF 中的所有数据帧的所有列的列表,然后他们应该 select 他们希望看到哪些列,然后我使用 matplotlib 向他们展示相应的数据。
数据
shape == (5730000, 339)
看起来一点也不大,这就是为什么我很困惑......(随着时间的推移可能会得到更多的行,列应该保持固定)
在第一步中,我迭代地附加行和列(运行正常),但一旦完成,我总是一次处理整个 DataFrame,仅分组或删除数据。
我的做法
- 我在内存中进行所有操作,因为 pandas 似乎相当快而 I/O 较慢(我认为 HDF 在不同的物理服务器上)
- 我使用日期时间索引并自动 selected 浮点数或整数列
- 我用
hdf.put('/name', df, format='fixed')
保存了这些步骤,因为 hdf.put('/name'.format(grp), df, format='table', data_columns=True)
似乎太慢了。
- 我使用例如
df.groupby(df.index).first()
和 df.groupby(pd.Grouper(freq='30Min')).agg(agg_dict)
来处理数据,其中 agg_dict 是一个字典,每列一个函数。这也非常慢。
- 为了绘图,我必须读入整个数据框然后获取列:
hdfstore.get('/name').columns
问题
- 如何在不从 HDFStore 读取任何数据的情况下检索所有列?
- 存储数据的最有效方式是什么? HDF 是正确的选择吗? Table 还是固定的?
- 如果索引是日期时间索引,它对效率有影响吗?通常是否存在更有效的格式(例如,所有列都相同,固定数据类型?)
- 有没有比
groupby
(df.groupby(pd.Grouper(freq='30Min')).agg(agg_dict)
) 更快的聚合方法
类似问题
How to access single columns using .select
我看到我可以使用它来仅检索某些列,但我认为只有在我知道列名之后。
感谢您的任何建议!
对于 HDFStore hdf
和 key
(来自 hdf.keys()
),您可以通过以下方式获取列名:
# Table stored with hdf.put(..., format='table')
columns = hdf.get_node('{}/table'.format(key)).description._v_names
# Table stored with hdf.put(..., format='fixed')
columns = list(hdf.get_node('{}/axis0'.format(key)).read().astype(str))
请注意 hdf.get(key).columns
也可以工作,但它将所有数据读入内存,而上述方法仅读取列名。
完整的工作示例:
#!/usr/bin/env python
import pandas as pd
data = pd.DataFrame({'a': [1,1,1,2,3,4,5], 'b': [2,3,4,1,3,2,1]})
with pd.HDFStore(path='store.h5', mode='a') as hdf:
hdf.put('/DATA/fixed_store', data, format='fixed')
hdf.put('/DATA/table_store', data, format='table', data_columns=True)
for key in hdf.keys():
try:
# column names of table store
print(hdf.get_node('{}/table'.format(key)).description._v_names)
except AttributeError:
try:
# column names of fixed store
print(list(hdf.get_node('{}/axis0'.format(key)).read().astype(str)))
except AttributeError:
# e.g. a dataset created by h5py instead of pandas.
print('unknown node in HDF.')
您可以通过指定相同的 start
和 stop
属性来简单地加载 DataFrame 的 0 行。并为 pandas 本身保留所有内部 index/column 处理:
idx = pd.MultiIndex.from_product([('A', 'B'), range(2)], names=('Alpha', 'Int'))
df = pd.DataFrame(np.random.randn(len(idx), 3), index=idx, columns=('I', 'II', 'III'))
df
>>> I II III
>>> Alpha Int
>>> A 0 -0.472412 0.436486 0.354592
>>> 1 -0.095776 -0.598585 -0.847514
>>> B 0 0.107897 1.236039 -0.196927
>>> 1 -0.154014 0.821511 0.092220
以下适用于 fixed
和 table
格式:
with pd.HDFStore('test.h5') as store:
store.put('df', df, format='f')
meta = store.select('df', start=1, stop=1)
meta
meta.index
meta.columns
>>> I II III
>>> Alpha Int
>>>
>>> MultiIndex(levels=[[], []],
>>> codes=[[], []],
>>> names=['Alpha', 'Int'])
>>>
>>> Index(['I', 'II', 'III'], dtype='object')
至于其他问题:
- 只要您的数据大部分是同类的(就像您提到的几乎是浮动列)并且您能够将其存储在单个文件中而无需跨机器分发数据 - HDF 是第一个尝试的方法。
- 如果您需要 append/delete/query 数据 - 您必须使用
table
格式。如果您只需要写入一次并读取多次 - fixed
将提高性能。
- 至于日期时间索引,我想这里我们可以使用与第 1 条中相同的想法。如果您能够将所有数据转换为单一类型,它应该会提高您的性能。
- 没有想到在评论您的问题时提出的任何其他建议。
- 没有读取任何数据的列:
store.get_storer('df').ncols # substitute 'df' with your key
# you can also access nrows and other useful fields
- 来自文档 (fixed format, table format):(粗体 中的要点)
[fixed] These types of stores are not appendable once written (though you can simply remove them and rewrite). Nor are they queryable; they must be retrieved in their entirety. They also do not support dataframes with non-unique column names. The fixed format stores offer very fast writing and slightly faster reading than table stores.
[table] Conceptually a table is shaped very much like a DataFrame, with rows and columns. A table may be appended to in the same or other sessions. In addition, delete and query type operations are supported.
您可以尝试使用纪元(或纪元)(从纪元开始的毫秒或纳秒)代替日期时间。这样,您只需处理整数索引。
如果您需要对大数据进行分组,您可以看看this answer。
一个建议:如果你有4个问题要问,最好在SO上单独问4个问题。这样,您将获得更多(更高质量)的答案,因为每个答案都更容易解决。每个人都会处理一个特定的主题,这样可以更轻松地搜索正在寻找特定答案的人。
我有一些问题 pandas' HDFStore
太慢了,不幸的是我无法从这里的其他问题中找到令人满意的解决方案。
情况
我有一个大 DataFrame,主要包含浮点数,有时包含整数列,这些列经过多个处理步骤(重命名、删除错误条目、按 30 分钟聚合)。每行都有一个与之关联的时间戳。我想将一些中间步骤保存到HDF文件中,以便用户可以迭代地执行单个步骤而无需每次都从头开始。
此外,用户应该能够从这些保存中绘制某些列,以便 select 坏数据。因此我只想检索列名而不读取 HDFStore 中的数据。 具体来说,用户应该获得存储在 HDF 中的所有数据帧的所有列的列表,然后他们应该 select 他们希望看到哪些列,然后我使用 matplotlib 向他们展示相应的数据。
数据shape == (5730000, 339)
看起来一点也不大,这就是为什么我很困惑......(随着时间的推移可能会得到更多的行,列应该保持固定)
在第一步中,我迭代地附加行和列(运行正常),但一旦完成,我总是一次处理整个 DataFrame,仅分组或删除数据。
我的做法
- 我在内存中进行所有操作,因为 pandas 似乎相当快而 I/O 较慢(我认为 HDF 在不同的物理服务器上)
- 我使用日期时间索引并自动 selected 浮点数或整数列
- 我用
hdf.put('/name', df, format='fixed')
保存了这些步骤,因为hdf.put('/name'.format(grp), df, format='table', data_columns=True)
似乎太慢了。 - 我使用例如
df.groupby(df.index).first()
和df.groupby(pd.Grouper(freq='30Min')).agg(agg_dict)
来处理数据,其中 agg_dict 是一个字典,每列一个函数。这也非常慢。 - 为了绘图,我必须读入整个数据框然后获取列:
hdfstore.get('/name').columns
问题
- 如何在不从 HDFStore 读取任何数据的情况下检索所有列?
- 存储数据的最有效方式是什么? HDF 是正确的选择吗? Table 还是固定的?
- 如果索引是日期时间索引,它对效率有影响吗?通常是否存在更有效的格式(例如,所有列都相同,固定数据类型?)
- 有没有比
groupby
(df.groupby(pd.Grouper(freq='30Min')).agg(agg_dict)
) 更快的聚合方法
类似问题
How to access single columns using .select
我看到我可以使用它来仅检索某些列,但我认为只有在我知道列名之后。
感谢您的任何建议!
对于 HDFStore hdf
和 key
(来自 hdf.keys()
),您可以通过以下方式获取列名:
# Table stored with hdf.put(..., format='table')
columns = hdf.get_node('{}/table'.format(key)).description._v_names
# Table stored with hdf.put(..., format='fixed')
columns = list(hdf.get_node('{}/axis0'.format(key)).read().astype(str))
请注意 hdf.get(key).columns
也可以工作,但它将所有数据读入内存,而上述方法仅读取列名。
完整的工作示例:
#!/usr/bin/env python
import pandas as pd
data = pd.DataFrame({'a': [1,1,1,2,3,4,5], 'b': [2,3,4,1,3,2,1]})
with pd.HDFStore(path='store.h5', mode='a') as hdf:
hdf.put('/DATA/fixed_store', data, format='fixed')
hdf.put('/DATA/table_store', data, format='table', data_columns=True)
for key in hdf.keys():
try:
# column names of table store
print(hdf.get_node('{}/table'.format(key)).description._v_names)
except AttributeError:
try:
# column names of fixed store
print(list(hdf.get_node('{}/axis0'.format(key)).read().astype(str)))
except AttributeError:
# e.g. a dataset created by h5py instead of pandas.
print('unknown node in HDF.')
您可以通过指定相同的 start
和 stop
属性来简单地加载 DataFrame 的 0 行。并为 pandas 本身保留所有内部 index/column 处理:
idx = pd.MultiIndex.from_product([('A', 'B'), range(2)], names=('Alpha', 'Int'))
df = pd.DataFrame(np.random.randn(len(idx), 3), index=idx, columns=('I', 'II', 'III'))
df
>>> I II III
>>> Alpha Int
>>> A 0 -0.472412 0.436486 0.354592
>>> 1 -0.095776 -0.598585 -0.847514
>>> B 0 0.107897 1.236039 -0.196927
>>> 1 -0.154014 0.821511 0.092220
以下适用于 fixed
和 table
格式:
with pd.HDFStore('test.h5') as store:
store.put('df', df, format='f')
meta = store.select('df', start=1, stop=1)
meta
meta.index
meta.columns
>>> I II III
>>> Alpha Int
>>>
>>> MultiIndex(levels=[[], []],
>>> codes=[[], []],
>>> names=['Alpha', 'Int'])
>>>
>>> Index(['I', 'II', 'III'], dtype='object')
至于其他问题:
- 只要您的数据大部分是同类的(就像您提到的几乎是浮动列)并且您能够将其存储在单个文件中而无需跨机器分发数据 - HDF 是第一个尝试的方法。
- 如果您需要 append/delete/query 数据 - 您必须使用
table
格式。如果您只需要写入一次并读取多次 -fixed
将提高性能。 - 至于日期时间索引,我想这里我们可以使用与第 1 条中相同的想法。如果您能够将所有数据转换为单一类型,它应该会提高您的性能。
- 没有想到在评论您的问题时提出的任何其他建议。
- 没有读取任何数据的列:
store.get_storer('df').ncols # substitute 'df' with your key
# you can also access nrows and other useful fields
- 来自文档 (fixed format, table format):(粗体 中的要点)
[fixed] These types of stores are not appendable once written (though you can simply remove them and rewrite). Nor are they queryable; they must be retrieved in their entirety. They also do not support dataframes with non-unique column names. The fixed format stores offer very fast writing and slightly faster reading than table stores.
[table] Conceptually a table is shaped very much like a DataFrame, with rows and columns. A table may be appended to in the same or other sessions. In addition, delete and query type operations are supported.
您可以尝试使用纪元(或纪元)(从纪元开始的毫秒或纳秒)代替日期时间。这样,您只需处理整数索引。
如果您需要对大数据进行分组,您可以看看this answer。
一个建议:如果你有4个问题要问,最好在SO上单独问4个问题。这样,您将获得更多(更高质量)的答案,因为每个答案都更容易解决。每个人都会处理一个特定的主题,这样可以更轻松地搜索正在寻找特定答案的人。