1

(Python 3.3 と Pandas 0.12 を使用)

私の質問は 2 つの部分で構成されています。

初め

このソリューションと一意のインデックスを作成するためのこのソリューションに基づいて、複数の csv ファイル (合計で約 8GB) を HDF5 ストアに繰り返し読み取り/追加しようとしています。私がこれを始めた理由は、そうすることでファイルが高速にアクセスでき、サイズが比較的小さくなり、メモリに読み込むことができると読んだからです。しかし、結局のところ、18GB の大きな h5 ファイルを取得します。私の (Windows) ラップトップには 8GB の RAM が搭載されています。私の最初の質問は、結果の h5 が元の csv ファイルの合計よりもはるかに大きいのはなぜですか? 2 番目の質問は、テーブルで一意のインデックスを実際に取得できないのはなぜですか?

私のコードは次のとおりです。

def to_hdf(path):
    """ Function that reads multiple csv files to HDF5 Store """
    # If path exists delete it such that a new instance can be created
    if os.path.exists(path):
        os.remove(path)
    # Creating HDF5 Store
    store = pd.HDFStore(path)

    # Reading csv files from list_files function
    with pd.get_store(path) as store:
        for f in list_files():
            try:
                # Creating reader in chunks -- reduces memory load
                df = pd.read_csv(f, encoding='utf-8', chunksize=50000, index_col=False)
                try:
                    nrows = store.get_storer('ta_store').nrows
                except:
                    nrows = 0
                # Looping over chunks and storing them in store file, node name 'ta_data'
                for chunk in df:
                    # Append chunk to store called 'ta_data'
                    store.append('ta_data', chunk, index=False, min_itemsize={'Placement Ref': 50, 'Click Ref': 50})
            # Print filename if corrupt (i.e. CParserError)
            except (parser.CParserError, ValueError) as detail:
                print(f, detail)

    print("Finished reading to HDF5 store, continuing processing data.")

2番

スクリプトの 2 番目の部分では、HDF5 ストアを Pandas DataFrame に読み込みます。なんで?csvファイルに出力したい最終データを取得するには、データ変換とフィルタリングを行う必要があるためです。ただし、HDF5 ストアを読み取ろうとするとMemoryError、次のコードを使用して が表示されます。

def read_store(filename, node):
    df = pd.read_hdf(filename, node)
    # Some data transformation and filtering code below

このエラーが発生した別の例は、次の関数を使用してインデックスが一意ではないことを示すためにストアを印刷したかった場合です。

def print_store(filename, node):
    store = pd.HDFStore(filename)
    print(store.select(node))

ここでの私の質問は、まず、この MemoryError の問題をどのように克服できるかです。hdf5 ファイルのサイズを小さくする必要があると思いますが、プログラミング/python/pandas にはまったく慣れていないので、ご意見をいただければ幸いです。次に、ストアを Pandas DataFrame に読み込むことが、データ変換 (1 つの新しい列の作成) とフィルタリング (文字列と日時の値に基づく) を行う最も効率的な方法であるかどうか疑問に思っています。

どんな助けでも大歓迎です!ありがとう :)

編集

要求に応じて、csv ファイルからの打ち切りサンプル (最初) とptdump -av(下)からの結果

csv サンプル

A               B   C               D       E           F           G         H                       I                   J       K               L                               M           N       O
4/28/2013 0:00  1   4/25/2013 20:34 View    Anon 2288 optional1   Optional2   Anon | 306742    252.027.323-306742  8.05    10303:41916417  14613669178715620788:10303      Duplicate   Anon  Display
4/28/2013 0:00  2   4/27/2013 13:40 View    Anon 2289 optional1   Optional2   Anon | 306742    252.027.323-306742  8.05    10303:41916417  14613669178715620788:10303      Duplicate   Anon  Display
4/28/2013 0:00  1   4/27/2013 23:41 View    Anon 5791 optional1   Optional2   Anon | 304142    478.323.464-304142  20.66   10304:37464168  14613663710835083509:10305      Duplicate   Anon  Display
4/28/2013 0:00  1   4/27/2013 16:18 View    Anon 4300 optional1   Optional2   Anon | 304142    196.470.934-304142  3.12    10303:41916420  15013670724970033908:291515610  Normal      Anon  Display

ptdump-av

/ (RootGroup) ''
  /._v_attrs (AttributeSet), 4 attributes:
   [CLASS := 'GROUP',
    PYTABLES_FORMAT_VERSION := '2.1',
    TITLE := '',
    VERSION := '1.0']
/ta_data (Group) ''
  /ta_data._v_attrs (AttributeSet), 14 attributes:
   [CLASS := 'GROUP',
    TITLE := '',
    VERSION := '1.0',
    data_columns := ['F', 'G'],
    encoding := 'UTF-8',
    index_cols := [(0, 'index')],
    info := {'index': {}},
    levels := 1,
    nan_rep := 'nan',
    non_index_axes := [(1, ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'])],
    pandas_type := 'frame_table',
    pandas_version := '0.10.1',
    table_type := 'appendable_frame',
    values_cols := ['values_block_0', 'values_block_1', 'values_block_2', 'F', 'G']]
/ta_data/table (Table(41957511,)) ''
  description := {
  "index": Int64Col(shape=(), dflt=0, pos=0),
  "values_block_0": Float64Col(shape=(1,), dflt=0.0, pos=1),
  "values_block_1": Int64Col(shape=(1,), dflt=0, pos=2),
  "values_block_2": StringCol(itemsize=30, shape=(11,), dflt=b'', pos=3),
  "F": StringCol(itemsize=50, shape=(), dflt=b'', pos=4),
  "G": StringCol(itemsize=50, shape=(), dflt=b'', pos=5)}
  byteorder := 'little'
  chunkshape := (288,)
  /ta_data/table._v_attrs (AttributeSet), 27 attributes:
   [CLASS := 'TABLE',
    G_dtype := 'bytes400',
    G_kind := ['G'],
    FIELD_0_FILL := 0,
    FIELD_0_NAME := 'index',
    FIELD_1_FILL := 0.0,
    FIELD_1_NAME := 'values_block_0',
    FIELD_2_FILL := 0,
    FIELD_2_NAME := 'values_block_1',
    FIELD_3_FILL := b'',
    FIELD_3_NAME := 'values_block_2',
    FIELD_4_FILL := b'',
    FIELD_4_NAME := 'F',
    FIELD_5_FILL := b'',
    FIELD_5_NAME := 'G',
    NROWS := 41957511,
    F_dtype := 'bytes400',
    F_kind := ['F'],
    TITLE := '',
    VERSION := '2.7',
    index_kind := 'integer',
    values_block_0_dtype := 'float64',
    values_block_0_kind := ['J'],
    values_block_1_dtype := 'int64',
    values_block_1_kind := ['B'],
    values_block_2_dtype := 'bytes240',
    values_block_2_kind := ['E', 'O', 'A', 'H', 'C', 'D', 'L', 'N', 'M', 'K', 'I']]

変換とフィルタリングの例

df['NewColumn'] = df['I'].str.split('-').str[0]

mask = df.groupby('NewColumn').E.transform(lambda x: x.nunique() == 1).astype('bool')
df = df[mask]
4

1 に答える 1

2
  • csv の日付を解析する必要がありparse_dates = ['A','C']ますread_csv。そうしないと、df.get_dtype_count()これらdatetime64[ns]は文字列であり、大きなストレージスペースを必要とし、操作が容易ではありません

  • min_itemsize引数は、この文字列列の最小サイズを指定します( 'F','G' の場合)。これは、文字列がこの制限を超えないことを保証するためだけです。ただし、その列のすべての行をその幅にします。これを下げることができれば、ストレージサイズが削減されます

  • 一意のインデックスを作成していません。上記のコードには行がありません。df.index = Series(df.index) + nrows読んだら追記read_csv

  • csv ファイルと同じように、hdf をチャンク単位で反復処理する必要があります。こちらをご覧ください。圧縮に関するドキュメントはこちらをご覧ください

フィルタリングが実際に何をするのかは明確ではありません。もう少し説明していただけますか?HDF ストレージがどのように機能するかを完全に理解する必要があります (たとえば、行を追加できますが、列は追加できません。変換/フィルター処理された forw を追加する結果テーブルを作成する必要がある可能性があります)。また、インデックスがどのように機能するかを理解する必要があります。これらの行にアクセスする方法が必要です (これはグローバルで一意ですが、データの構造によっては必要ない場合があります)。

于 2013-08-20T12:33:40.793 に答える