【问题标题】:Pandas get specific rows from HDF5 by indexPandas 通过索引从 HDF5 获取特定行
【发布时间】:2015-08-09 14:45:53
【问题描述】:

我有一个已写入 HDF5 文件的 pandas DataFrame。数据按时间戳索引,如下所示:

In [5]: df
Out[5]:
                          Codes   Price  Size
Time
2015-04-27 01:31:08-04:00     T  111.75    23
2015-04-27 01:31:39-04:00     T  111.80    23
2015-04-27 01:31:39-04:00     T  113.00    35
2015-04-27 01:34:14-04:00     T  113.00    85
2015-04-27 01:55:15-04:00     T  113.50   203
...                         ...     ...   ...
2015-05-26 11:35:00-04:00    CA  110.55   196
2015-05-26 11:35:00-04:00    CA  110.55    98
2015-05-26 11:35:00-04:00    CA  110.55   738
2015-05-26 11:35:00-04:00    CA  110.55    19
2015-05-26 11:37:01-04:00        110.55    12

我想要创建一个函数,我可以传递一个熊猫DatetimeIndex,它会返回一个 DataFrame,其中的行位于 DatetimeIndex 中每个时间戳之前或之前。

我遇到的问题是,如果我要查找的行数超过 30 行,则串联的 read_hdf 查询将不起作用——请参阅 [pandas read_hdf with 'where' condition limitation?

我现在正在做的是这样的,但必须有更好的解决方案:

from pandas import read_hdf, DatetimeIndex
from datetime import timedelta
import pytz

def getRows(file, dataset, index):

    if len(index) == 1:
        start = index.date[0]
        end = (index.date + timedelta(days=1))[0]
    else:
        start = index.date.min()
        end = (index.date.max() + timedelta(days=1))

    where = '(index >= "' + str(start) + '") & (index < "' str(end) + '")'

    df = read_hdf(file, dataset, where=where)

    df = df.groupby(level=0).last().reindex(index, method='pad')

    return df

【问题讨论】:

    标签: python pandas hdf5


    【解决方案1】:

    这是使用where mask的示例

    In [22]: pd.set_option('max_rows',10)
    
    In [23]: df = DataFrame({'A' : np.random.randn(100), 'B' : pd.date_range('20130101',periods=100)}).set_index('B')
    
    In [24]: df
    Out[24]: 
                       A
    B                   
    2013-01-01  0.493144
    2013-01-02  0.421045
    2013-01-03 -0.717824
    2013-01-04  0.159865
    2013-01-05 -0.485890
    ...              ...
    2013-04-06 -0.805954
    2013-04-07 -1.014333
    2013-04-08  0.846877
    2013-04-09 -1.646908
    2013-04-10 -0.160927
    
    [100 rows x 1 columns]
    

    存储测试帧

    In [25]: store = pd.HDFStore('test.h5',mode='w')
    
    In [26]: store.append('df',df)
    

    创建随机选择的日期。

    In [27]: dates = df.index.take(np.random.randint(0,100,10))
    
    In [28]: dates
    Out[28]: DatetimeIndex(['2013-03-29', '2013-02-16', '2013-01-15', '2013-02-06', '2013-01-12', '2013-02-24', '2013-02-18', '2013-01-06', '2013-03-17', '2013-03-21'], dtype='datetime64[ns]', name=u'B', freq=None, tz=None)
    

    选择索引列(全部)

    In [29]: c = store.select_column('df','index')
    
    In [30]: c
    Out[30]: 
    0    2013-01-01
    1    2013-01-02
    2    2013-01-03
    3    2013-01-04
    4    2013-01-05
            ...    
    95   2013-04-06
    96   2013-04-07
    97   2013-04-08
    98   2013-04-09
    99   2013-04-10
    Name: B, dtype: datetime64[ns]
    

    选择所需的索引器。这实际上可能有点复杂,例如你可能想要.reindex(method='nearest')

    In [34]: c[c.isin(dates)] 
    Out[34]: 
    5    2013-01-06
    11   2013-01-12
    14   2013-01-15
    36   2013-02-06
    46   2013-02-16
    48   2013-02-18
    54   2013-02-24
    75   2013-03-17
    79   2013-03-21
    87   2013-03-29
    Name: B, dtype: datetime64[ns]
    

    选择你想要的行

    In [32]: store.select('df',where=c[c.isin(dates)].index)
    Out[32]: 
                       A
    B                   
    2013-01-06  0.680930
    2013-01-12  0.165923
    2013-01-15 -0.517692
    2013-02-06 -0.351020
    2013-02-16  1.348973
    2013-02-18  0.448890
    2013-02-24 -1.078522
    2013-03-17 -0.358597
    2013-03-21 -0.482301
    2013-03-29  0.343381
    
    In [33]: store.close()
    

    【讨论】:

    • 谢谢——我在使用这种方法时遇到的问题是,对于非常大的数据集,我在将整个索引列拉入内存时遇到了内存问题。因此,我正在寻找一种方法来直接按 HDF5 表上的索引列表进行切片,而无需将任何内容拉入内存
    • 真的,您不能将单列拉入内存(请注意,您必须完全使用我在上面所做的,select_column),而不是常规选择,它只会将该单列拉入记忆。常规选择会重新索引并且会使用大量内存。数据集有多大,内存有多少?假设您使用的是 64 位。
    • 在将整个数据集拉入内存时遇到了内存问题,这就是我开始使用 read_hdf 查询方法的原因。我正在处理的数据集大约有 10m 行,3 列,我在从 HDF5 加载集合时遇到了内存错误。不幸的是,必须在 Windows 下使用 32 位。我试试你的方法!!!!理想情况下,我只需将集合读入内存一次,因为所有 IO 都会大大减慢我的操作速度
    • 我有 8GB 内存将在接下来的几天内升级到 24GB 也许这可以让我预先加载所有内容
    • 32 但在 windows 上有 2gb(最多限制);你应该简单地安装 64 位 Python
    猜你喜欢
    • 2019-06-05
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多