【问题标题】:Python (pandas): store a data frame in hdf5 with a multi indexPython(熊猫):将数据帧存储在具有多索引的hdf5中
【发布时间】:2014-09-13 14:23:38
【问题描述】:

我需要使用具有多索引的大尺寸数据框,因此我尝试创建一个数据框来学习如何将其存储在 hdf5 文件中。 数据框是这样的:(前2列有多重索引)

Symbol    Date          0

C         2014-07-21    4792
B         2014-07-21    4492
A         2014-07-21    5681
B         2014-07-21    8310
A         2014-07-21    1197
C         2014-07-21    4722
          2014-07-21    7695
          2014-07-21    1774

我正在使用 pandas.to_hdf,但当我尝试选择组中的数据时,它会创建一个“固定格式存储”:

store.select('table','Symbol == "A"')

它返回一些错误,主要问题是这个

TypeError: cannot pass a where specification when reading from a Fixed format store. this store must be selected in its entirety

然后我尝试像这样附加 DataFrame:

store.append('ts1',timedata)

这应该创建一个表,但这给了我另一个错误:

TypeError: [unicode] is not implemented as a table column

所以我需要代码以 hdf5 格式将数据帧存储在表中并从单个索引中选择数据(为此我找到了此代码:store.select('timedata','Symbol == "A"')

【问题讨论】:

  • 请报告您的 pandas 版本、numpy 版本、python 版本、操作系统,并展示您是如何创建该框架的。
  • pandas 0.14.1、numpy 1.8.1 系统版本 2.7.7 |Anaconda 2.0.1 (x86_64)| (默认,2014 年 6 月 2 日,12:48:16)\n[GCC 4.0.1(Apple Inc. build 5493)]
  • 我创建了从我用随机数据、随机随机符号和随机数量创建的 sqlite3 数据帧中提取数据的数据帧:
    doubleIndex = c.execute("SELECT date, symbol, qty FROM stocks") double = c.fetchall() serie = pandas.DataFrame(double,columns=['Date','Symbol', 'DateValue']) serie['Date'] = pandas.to_datetime(serie['Date']) serie = serie.sort('Date',ascending=True)
  • 这就是我创建 MultiIndex 的方式:index = pandas.MultiIndex.from_arrays([serie['Symbol'],serie['Date']], names=['Symbol','Date'])
  • 你可能有 unicode,尝试df[column] = df[column].astype(str) 将 unicode 更改为字符串。无法在 py2.7 中存储 unicode。您也应该使用read_sql(并且可能关闭 sqlite3 中的 unicode 选项)

标签: python sql pandas hdf5 multi-index


【解决方案1】:

杰夫的答案完全正确。我发现了一些我想分享的问题,但它不适合评论 - 请考虑这只是一个长篇附加评论:)

(Pytables 版本) 如果您在尝试编写 hdf 文件时遇到缺少属性或方法错误,您可能需要尝试更新您的 PyTables 版本。 Pandas(在撰写本文时)利用了 Pytables,我发现至少有一对版本会引发一些奇怪的错误,直到我更新 Pytables 并重新加载。

(数据类型) 这可能在 Python 3 中得到修复,但在 2.7x 中,to_hdf 存在 unicode、混合数据类型列和浮点 NaN 值的问题。下面是一个示例实用程序函数,用于清理 DataFrame 以准备写入 to_hdf,它为我解决了所有这些问题。请注意,这会将 NaN 替换为零,这适用于我的应用程序,但您可能需要对其进行调整:

def clean_cols_for_hdf(data):
    types = data.apply(lambda x: pd.lib.infer_dtype(x.values))
    for col in types[types=='mixed'].index:
        data[col] = .data[col].astype(str)
    data[<your appropriate columns here>].fillna(0,inplace=True)
    return data

其中一些也只是扩展了 Jeff 的 cmets 之一。杰夫很棒,请原谅添加的答案,但我想补充一些为我解决问题的细节。

【讨论】:

  • 这将填充 Na,但不会解决 unicode 问题
  • @MonicaHeddneck - 你试过发现没有吗?修复 unicode 是我代码中的 .astype(str) 的用途,至少当我现在尝试一些简单的示例时,它至少可以在 Python 2.7 上运行。您是否有无法处理的具体案例?
  • 是的,由于某种原因它对我不起作用。我在 Python 2.7 中。不知道为什么。我最终放弃了。
  • @MonicaHeddneck - 无赖。没有例子很难知道发生了什么,但我相信 - unicode 是一团糟,而且随着时间的推移似乎变得更糟。
【解决方案2】:

这是一个例子

In [8]: pd.__version__
Out[8]: '0.14.1'

In [9]: np.__version__
Out[9]: '1.8.1'

In [10]: import sys

In [11]: sys.version
Out[11]: '2.7.3 (default, Jan  7 2013, 09:17:50) \n[GCC 4.4.5]'

In [4]: df = DataFrame(np.arange(9).reshape(9,-1),index=pd.MultiIndex.from_product([list('abc'),date_range('20140721',periods=3)],names=['symbol','date']),columns=['value'])

In [5]: df
Out[5]: 
                   value
symbol date             
a      2014-07-21      0
       2014-07-22      1
       2014-07-23      2
b      2014-07-21      3
       2014-07-22      4
       2014-07-23      5
c      2014-07-21      6
       2014-07-22      7
       2014-07-23      8

In [6]: df.to_hdf('test.h5','df',mode='w',format='table')

In [7]: pd.read_hdf('test.h5','df',where='date=20140722')
Out[7]: 
                   value
symbol date             
a      2014-07-22      1
b      2014-07-22      4
c      2014-07-22      7

In [12]: pd.read_hdf('test.h5','df',where='symbol="a"')
Out[12]: 
                   value
symbol date             
a      2014-07-21      0
       2014-07-22      1
       2014-07-23      2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-05
    • 2018-04-18
    • 1970-01-01
    • 2020-12-02
    • 2014-11-13
    • 2020-08-22
    • 2020-08-30
    • 2020-01-14
    相关资源
    最近更新 更多