(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]