web-dev-qa-db-ja.com

フォルダ内の複数の寄木細工のファイルを読み取り、python)を使用して単一のcsvファイルに書き込みます

私はpythonに不慣れで、ファイル名が順番に付いた複数の寄木細工のファイルがあるシナリオがあります。例:par_file1、par_file2、par_file3など。フォルダー内に最大100個のファイルがあります。

これらの寄木細工のファイルをfile1から順番に読み取り、単一のcsvファイルに書き込む必要があります。 file1の内容を書き込んだ後、file2の内容をヘッダーなしで同じcsvに追加する必要があります。すべてのファイルの列名は同じであり、データのみが複数のファイルに分割されることに注意してください。

次のコードでpyarrowを使用して、単一の寄木細工の床をcsvファイルに変換する方法を学びました。

import pandas as pd    
df = pd.read_parquet('par_file.parquet')    
df.to_csv('csv_file.csv')

しかし、これを拡張して複数の寄木細工のファイルをループし、単一のcsvに追加することはできませんでした。 pandasにこれを行う方法はありますか?またはこれを行う他の方法は非常に役立ちます。ありがとうございます。

2
Pri31

ファイルをローカルマシンにコピーしてコードを実行する場合は、次のようにすることができます。以下のコードは、寄木細工のファイルと同じディレクトリでコードを実行していることを前提としています。また、上記で指定したファイルの名前を想定しています。「order。ex:par_file1、par_file2、par_file3など。フォルダ内の最大100個のファイル。」ファイルを検索する必要がある場合は、globを使用してファイル名を取得し、csvを保存するパスを明示的に指定する必要があります。open(r'this\is\your\path\to\csv_file.csv', 'a')これがお役に立てば幸いです。

import pandas as pd

# Create an empty csv file and write the first parquet file with headers
with open('csv_file.csv','w') as csv_file:
    print('Reading par_file1.parquet')
    df = pd.read_parquet('par_file1.parquet')
    df.to_csv(csv_file, index=False)
    print('par_file1.parquet appended to csv_file.csv\n')
    csv_file.close()

# create your file names and append to an empty list to look for in the current directory
files = []
for i in range(2,101):
    files.append(f'par_file{i}.parquet')

# open files and append to csv_file.csv
for f in files:
    print(f'Reading {f}')
    df = pd.read_parquet(f)
    with open('csv_file.csv','a') as file:
        df.to_csv(file, header=False, index=False)
        print(f'{f} appended to csv_file.csv\n')

必要に応じて、printステートメントを削除できます。

python 3.6を使用してpandas 0.23.3でテスト済み

1
Chris

pandasがパーティション化された寄木細工のデータセットをネイティブに読み取ることができるかどうかを確認するためにこの質問に遭遇しました。現在の答えは不必要に冗長である(解析が困難になっている)と言わざるを得ません。サイズに応じて、ファイルハンドルを常に開いたり閉じたりして、最後までスキャンするのは特に効率的ではありません。

より良い代替策は、すべての寄木細工のファイルを単一のDataFrameに読み取り、それを1回書き込むことです。

from pathlib import Path
import pandas as pd

data_dir = Path('dir/to/parquet/files')
full_df = pd.concat(
    pd.read_parquet(parquet_file)
    for parquet_file in data_dir.glob('*.parquet')
)
full_df.to_csv('csv_file.csv')

または、本当にファイルに追加したい場合:

data_dir = Path('dir/to/parquet/files')
for i, parquet_path in enumerate(data_dir.glob('*.parquet')):
    df = pd.read_parquet(parquet_path)
    write_header = i == 0 # write header only on the 0th file
    write_mode = 'w' if i == 0 else 'a' # 'write' mode for 0th file, 'append' otherwise
    df.to_csv('csv_file.csv', mode=write_mode, header=write_header)

開始時にターゲットCSVファイルを"a+"モードで開く各ファイルを追加するための最後の代替手段で、書き込み/追加ごとにファイルハンドルをファイルの最後までスキャンし続けます(これは機能すると思いますが、機能していません) 実際にテスト済み):

data_dir = Path('dir/to/parquet/files')
with open('csv_file.csv', "a+") as csv_handle:
    for i, parquet_path in enumerate(data_dir.glob('*.parquet')):
        df = pd.read_parquet(parquet_path)
        write_header = i == 0 # write header only on the 0th file
        df.to_csv(csv_handle, header=write_header)
16
PMende

これは、すべての寄木細工のファイルを1つのデータフレームにロードするのに役立ちました

import glob
 files = glob.glob("*.snappy.parquet")
 data = [pd.read_parquet(f,engine='fastparquet') for f in files]
 merged_data = pd.concat(data,ignore_index=True)
2
Puttur Kamath