Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在追加失败时高效地重建pandas hdfstore表

如何在追加失败时高效地重建pandas hdfstore表
EN

Stack Overflow用户
提问于 2016-03-05 18:50:28
回答 1查看 1K关注 0票数 4

我正在努力使用pandas中的hdfstore来处理正在进行的迭代过程中的数据帧。在每次迭代中,我都会追加到hdfstore中的一个表中。下面是一个玩具示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import pandas as pd
from pandas import HDFStore
import numpy as np
from random import choice
from string import ascii_letters
alphanum=np.array(list(ascii_letters)+range(0,9))
def hdfstore_append(storefile,key,df,format="t",columns=None,data_columns=None):
    if df is None:
        return
    if key[0]!='/':
        key='/'+key
    with HDFStore(storefile) as store:
        if key not in store.keys():
            store.put(key,df,format=format,columns=columns,data_columns=data_columns)
        else:
            try:
                store.append(key,df)
            except Exception as inst:
                df = pd.concat([store.get(key),df])
                store.put(key,df,format=format,columns=columns,
                          data_columns=data_columns)

storefile="db.h5"
for i in range(0,100):
    df=pd.DataFrame([dict(n=np.random.randn(),
                       s=''.join(alphanum[np.random.randint(1,len(alphanum),np.random.randint(1,2*(i+1))]))],index=[i])
    hdfstore_append(storefile,'/SO/df',df,columns=df.columns,data_columns=True)

hdfstore_append函数可防止hdfstore.append抛出的各种异常,并在必要时重新构建表。这种方法的问题是,当存储中的表变得非常大时,它会变得非常慢。

有没有更有效的方法来做到这一点?

EN

回答 1

Stack Overflow用户

发布于 2016-03-15 05:34:16

下面是一个构建大型熊猫hdfstore的有效方法的示例。关键是当表变大时缓存帧编号。此外,删除预先存在的数据将实质上创建一个put,而不是附加。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import six
import logging
import os
from abc import ABCMeta, abstractmethod, abstractproperty
import warnings

import pandas as pd

logger = logging.getLogger(__name__)


class FramewiseData(object):
    "Abstract base class defining a data container with framewise access."

    __metaclass__ = ABCMeta

    @abstractmethod
    def put(self, df):
        pass

    @abstractmethod
    def get(self, frame_no):
        pass

    @abstractproperty
    def frames(self):
        pass

    @abstractmethod
    def close(self):
        pass

    @abstractproperty
    def t_column(self):
        pass

    def __getitem__(self, frame_no):
        return self.get(frame_no)

    def __len__(self):
        return len(self.frames)

    def dump(self, N=None):
        """Return data from all, or the first N, frames in a single DataFrame
        Parameters
        ----------
        N : integer
            optional; if None, return all frames
        Returns
        -------
        DataFrame
        """
        if N is None:
            return pd.concat(iter(self))
        else:
            i = iter(self)
            return pd.concat((next(i) for _ in range(N)))

    @property
    def max_frame(self):
        return max(self.frames)

    def _validate(self, df):
        if self.t_column not in df.columns:
            raise ValueError("Cannot write frame without a column "
                             "called {0}".format(self.t_column))
        if df[self.t_column].nunique() != 1:
            raise ValueError("Found multiple values for 'frame'. "
                             "Write one frame at a time.")

    def __iter__(self):
        return self._build_generator()

    def _build_generator(self):
        for frame_no in self.frames:
            yield self.get(frame_no)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.close()

KEY_PREFIX = 'Frame_'
len_key_prefix = len(KEY_PREFIX)


def code_key(frame_no):
    "Turn the frame_no into a 'natural name' string idiomatic of HDFStore"
    key = '{0}{1}'.format(KEY_PREFIX, frame_no)
    return key


def decode_key(key):
    frame_no = int(key[len_key_prefix:])
    return frame_no


class PandasHDFStore(FramewiseData):
    """An interface to an HDF5 file with framewise access, using pandas.
    Save each frame's data to a node in a pandas HDFStore.
    Any additional keyword arguments to the constructor are passed to
    pandas.HDFStore().
    """

    def __init__(self, filename, mode='a', t_column='frame', **kwargs):
        self.filename = os.path.abspath(filename)
        self._t_column = t_column
        self.store = pd.HDFStore(self.filename, mode, **kwargs)

    @property
    def t_column(self):
        return self._t_column

    @property
    def max_frame(self):
        return max(self.frames)

    def put(self, df):
        if len(df) == 0:
            warnings.warn('An empty DataFrame was passed to put(). Continuing.')
            return
        frame_no = df[self.t_column].values[0]  # validated to be all the same
        key = code_key(frame_no)
        # Store data as tabular instead of fixed-format.
        # Make sure remove any prexisting data, so don't really 'append'.
        try:
            self.store.remove(key)
        except KeyError:
            pass
        self.store.put(key, df, format='table')

    def get(self, frame_no):
        key = code_key(frame_no)
        frame = self.store.get(key)
        return frame

    @property
    def frames(self):
        """Returns sorted list of integer frame numbers in file"""
        return self._get_frame_nos()

    def _get_frame_nos(self):
        """Returns sorted list of integer frame numbers in file"""
        # Pandas' store.keys() scans the entire file looking for stored Pandas
        # structures. This is very slow for large numbers of frames.
        # Instead, scan the root level of the file for nodes with names
        # matching our scheme; we know they are DataFrames.
        r = [decode_key(key) for key in self.store.root._v_children.keys() if
             key.startswith(KEY_PREFIX)]
        r.sort()
        return r

    def close(self):
        self.store.close()


class PandasHDFStoreBig(PandasHDFStore):
    """Like PandasHDFStore, but keeps a cache of frame numbers.
    This can give a large performance boost when a file contains thousands
    of frames.
    If a file was made in PandasHDFStore, opening it with this class
    and then closing it will add a cache (if mode != 'r').
    Any additional keyword arguments to the constructor are passed to
    pandas.HDFStore().
    """

    def __init__(self, filename, mode='a', t_column='frame', **kwargs):
        self._CACHE_NAME = '_Frames_Cache'
        self._frames_cache = None
        self._cache_dirty = False  # Whether _frames_cache needs to be written out
        super(PandasHDFStoreBig, self).__init__(filename, mode, t_column,
                                                **kwargs)

    @property
    def frames(self):
        # Hit memory cache, then disk cache
        if self._frames_cache is not None:
            return self._frames_cache
        else:
            try:
                self._frames_cache = list(self.store[self._CACHE_NAME].index.values)
                self._cache_dirty = False
            except KeyError:
                self._frames_cache = self._get_frame_nos()
                self._cache_dirty = True # In memory, but not in file
            return self._frames_cache

    def put(self, df):
        self._invalidate_cache()
        super(PandasHDFStoreBig, self).put(df)

    def rebuild_cache(self):
        """Delete cache on disk and rebuild it."""
        self._invalidate_cache()
        _ = self.frames # Compute cache
        self._flush_cache()

    def _invalidate_cache(self):
        self._frames_cache = None
        try:
            del self.store[self._CACHE_NAME]
        except KeyError: pass

    def _flush_cache(self):
        """Writes frame cache if dirty and file is writable."""
        if (self._frames_cache is not None and self._cache_dirty
                and self.store.root._v_file._iswritable()):
            self.store[self._CACHE_NAME] = pd.DataFrame({'dummy': 1},
                                                        index=self._frames_cache)
            self._cache_dirty = False

    def close(self):
        """Updates cache, writes if necessary, then closes file."""
        if self.store.root._v_file._iswritable():
            _ = self.frames # Compute cache
            self._flush_cache()
        super(PandasHDFStoreBig, self).close()


class PandasHDFStoreSingleNode(FramewiseData):
    """An interface to an HDF5 file with framewise access,
    using pandas, that is faster for cross-frame queries.
    This implementation is more complex than PandasHDFStore,
    but it simplifies (speeds up?) cross-frame queries,
    like queries for a single probe's entire trajectory.
    Any additional keyword arguments to the constructor are passed to
    pandas.HDFStore().
    """

    def __init__(self, filename, key='FrameData', mode='a', t_column='frame',
                 use_tabular_copy=False, **kwargs):
        self.filename = os.path.abspath(filename)
        self.key = key
        self._t_column = t_column
        self.store = pd.HDFStore(self.filename, mode, **kwargs)

        with pd.get_store(self.filename) as store:
            try:
                store[self.key]
            except KeyError:
                pass
            else:
                self._validate_node(use_tabular_copy)

    @property
    def t_column(self):
        return self._t_column

    def put(self, df):
        if len(df) == 0:
            warnings.warn('An empty DataFrame was passed to put(). Continuing.')
            return
        self._validate(df)
        self.store.append(self.key, df, data_columns=True)

    def get(self, frame_no):
        frame = self.store.select(self.key, '{0} == {1}'.format(
            self._t_column, frame_no))
        return frame

    def dump(self, N=None):
        """Return data from all, or the first N, frames in a single DataFrame
        Parameters
        ----------
        N : integer
            optional; if None, return all frames
        Returns
        -------
        DataFrame
        """
        if N is None:
            return self.store.select(self.key)
        else:
            Nth_frame = self.frames[N - 1]
            return self.store.select(self.key, '{0} <= {1}'.format(
                self._t_column, Nth_frame))

    def close(self):
        self.store.close()

    def __del__(self):
        if hasattr(self, 'store'):
            self.close()

    @property
    def frames(self):
        """Returns sorted list of integer frame numbers in file"""
        # I assume one column can fit in memory, which is not ideal.
        # Chunking does not seem to be implemented for select_column.
        frame_nos = self.store.select_column(self.key, self.t_column).unique()
        frame_nos.sort()
        return frame_nos

    def _validate_node(self, use_tabular_copy):
        # The HDFStore might be non-tabular, which means we cannot select a
        # subset, and this whole structure will not work.
        # For convenience, this can rewrite the table into a tabular node.
        if use_tabular_copy:
            self.key = _make_tabular_copy(self.filename, self.key)

        pandas_type = getattr(getattr(getattr(
            self.store._handle.root, self.key, None), '_v_attrs', None),
            'pandas_type', None)
        if not pandas_type == 'frame_table':
            raise ValueError("This node is not tabular. Call with "
                             "use_tabular_copy=True to proceed.")


def _make_tabular_copy(store, key):
    """Copy the contents nontabular node in a pandas HDFStore
    into a tabular node"""
    tabular_key = key + '/tabular'
    logger.info("Making a tabular copy of %s at %s", (key, tabular_key))
    store.append(tabular_key, store.get(key), data_columns=True)
    return tabular_key
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35818327

复制
相关文章
如何在TensorFlow上高效地使用Dataset
【导读】近日,机器学习工程师Francesco Zuppichini发表一篇教程,讲解了在TensorFlow中高效地输入数据集的方法,作者首先抛弃了feed-dict(它太慢了),然后介绍Tenso
WZEARW
2018/04/13
10.4K0
如何在TensorFlow上高效地使用Dataset
解决ImportError: HDFStore requires PyTables, "No module named 'tables'" problem im
如果在Python中使用​​pandas​​库时遇到了以下错误信息:​​ImportError: HDFStore requires PyTables, "No module named 'tables'"​​,那么说明你的环境缺少​​PyTables​​库。 ​​PyTables​​是一个用于在Python中操作HDF5文件的库,而​​pandas​​使用了​​PyTables​​来支持HDF5数据的存储和读取。因此,在使用​​pandas​​来读取或存储HDF5文件时,需要先安装​​PyTables​​库。 下面是解决这个问题的步骤:
大盘鸡拌面
2023/10/25
5810
在pandas中利用hdf5高效存储数据
HDF5(Hierarchical Data Formal)是用于存储大规模数值数据的较为理想的存储格式。
朱卫军 AI Python
2022/04/03
2.9K0
在pandas中利用hdf5高效存储数据
在pandas中利用hdf5高效存储数据
HDF5(Hierarchical Data Formal)是用于存储大规模数值数据的较为理想的存储格式。
bugsuse
2020/10/09
5.5K0
在pandas中利用hdf5高效存储数据
程序员跳槽时,如何高效地准备面试?
今天和大家分享的主题是「程序员跳槽时,如何高效地准备面试?」,但其实今天主要涉及到的是 HR 在面试时有哪些套路,这样可以见招拆招,斩获 offer!
技术zhai
2019/02/15
9860
pandas | 如何在DataFrame中通过索引高效获取数据?
上篇文章当中我们简单介绍了一下DataFrame这个数据结构的一些常见的用法,从整体上大概了解了一下这个数据结构。今天这一篇我们将会深入其中索引相关的应用方法,了解一下DataFrame的索引机制和使用方法。
TechFlow-承志
2020/07/10
13.7K0
pandas | 如何在DataFrame中通过索引高效获取数据?
jQuery 追加元素的方法如append、prepend、before
jQuery after() 方法在被选元素之后插入内容。 jQuery before() 方法在被选元素之前插入内容。 实例
用户5640963
2019/07/28
1K0
Pandas-8. 重建索引
以上代码df1应该是3列10行,之后和df2对齐。 对齐操作列名应该匹配,无法对齐的列整列置为NAN。
悠扬前奏
2019/05/29
8060
索引重建失败的解决
在Oracle中创建索引,尤其是大的热表索引(存在很多的活动事务),如果在创建过程中出现异常,例如会话中断(OS层面kill-9),可能会导致Oracle数据字典内已经包含了该索引的信息(诸如像在ind$的标记位信息不能及时复位),但是却实际没有为该索引分配段,进而导致需要重新建立索引的时候,可能会抛出异常,如下所示,在删除索引IDX1时,会提示索引对象826976号正在创建或者被重建,无法删除,(在alter table ... drop partition的时候(Drop Partition Failed With ORA-08104: This Index Object Is Being Online Built Or Rebuilt (Doc ID 2358693.1)),可能出现相同的错误),
bisal
2019/10/26
1K0
如何在集群中高效地部署和使用 AI 芯片?
AI 研习社按:人工智能技术发展迅猛的背后不仅得益于庞大的数据量,更需要强大的硬件支持。面对层出不穷的 AI 应用,已经很难采用一种通用的硬件进行高效的数据计算和处理,这也促使了各种类型的 AI 芯片蓬勃发展。
AI研习社
2018/07/26
9930
如何在集群中高效地部署和使用 AI 芯片?
MySQL之重建表
在MySQL中,如果我们对大表频繁进行insert和delete操作,那么时间一长,这个表中会出现很多"空洞",也就是表碎片。
AsiaYe
2020/07/01
4.4K0
(数据科学学习手札63)利用pandas读写HDF5文件
  HDF5(Hierarchical Data Formal)是用于存储大规模数值数据的较为理想的存储格式,文件后缀名为h5,存储读取速度非常快,且可在文件内部按照明确的层次存储数据,同一个HDF5可以看做一个高度整合的文件夹,其内部可存放不同类型的数据。在Python中操纵HDF5文件的方式主要有两种,一是利用pandas中内建的一系列HDF5文件操作相关的方法来将pandas中的数据结构保存在HDF5文件中,二是利用h5py模块来完成从Python原生数据结构向HDF5格式的保存,本文就将针对pandas中读写HDF5文件的方法进行介绍。
Feffery
2019/07/08
2.2K0
(数据科学学习手札63)利用pandas读写HDF5文件
(数据科学学习手札63)利用pandas读写HDF5文件
  HDF5(Hierarchical Data Formal)是用于存储大规模数值数据的较为理想的存储格式,文件后缀名为h5,存储读取速度非常快,且可在文件内部按照明确的层次存储数据,同一个HDF5可以看做一个高度整合的文件夹,其内部可存放不同类型的数据。在Python中操纵HDF5文件的方式主要有两种,一是利用pandas中内建的一系列HDF5文件操作相关的方法来将pandas中的数据结构保存在HDF5文件中,二是利用h5py模块来完成从Python原生数据结构向HDF5格式的保存,本文就将针对pandas中读写HDF5文件的方法进行介绍。
Feffery
2019/07/06
1.3K0
Django删除表重建
可能是在建表之后又修改了mysql的配置,导致models中的CharField不支持汉字,调试了很久都不行,各种配置无果后决定删表重建
cywhat
2022/11/22
1K0
如何在MySQL高效的join3个表
若改写成straight_join,要怎么指定连接顺序,以及怎么给三个表创建索引?
JavaEdge
2021/12/07
4720
如何在MySQL高效的join3个表
若改写成straight_join,要怎么指定连接顺序,以及怎么给三个表创建索引?
JavaEdge
2021/10/18
1.2K0
5. Pandas系列 - 重建索引
rename()方法允许基于一些映射(字典或者系列)或任意函数来重新标记一个轴 参数有 column和index
Python编程爱好者
2020/09/08
9820
5. Pandas系列 - 重建索引
高效地加载Bitmap
一张2048x1536像素的图片,采用ARGB_8888进行存储,那么内存大小2048 x 1536 x 4 = 12M,如果inSampleSize = 4,那么采样后的图片内存大小:512 x 384 x 4 = 0.75M
用户1205080
2018/11/08
4840
SAP ABAP——内表(五)【追加内表数据—INSERT】
💬个人网站:【芒果个人日志】​​​​​​ 💬原文地址:SAP ABAP——内表(五)【追加内表数据—INSERT】 - 芒果个人日志 (wyz-math.cn) 💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后端的开发语言ABAP,SQL进行任务的完成,对SAP企业管理系统,SAP ABAP开发和数据库具有较深入的研究。 💅文章概要:本文
THUNDER王
2023/02/23
6780
SAP ABAP——内表(五)【追加内表数据—INSERT】
SAP ABAP——内表(六)【追加内表数据—APPEND】
💬个人网站:【芒果个人日志】​​​​​​ 💬原文地址: SAP ABAP——内表(六)【追加内表数据—APPEND】 - 芒果个人日志 (wyz-math.cn) 💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后端的开发语言ABAP,SQL进行任务的完成,对SAP企业管理系统,SAP ABAP开发和数据库具有较深入的研究。 💅文章概要:本文
THUNDER王
2023/02/23
1.4K0
SAP ABAP——内表(六)【追加内表数据—APPEND】

相似问题

追加HDFStore pandas TypeError

112

MultiIndex DataFrames的Pandas HDFStore :如何高效地获取所有索引

216

在HDFStore中追加“无法匹配现有表结构”失败

13

使用pandas将新列追加到HDFStore

120

min_itemsize设置为字符串列的最大值时,Pandas HDFStore:追加失败

1159
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文