ディレクトリからいくつかのcsvファイルをパンダに読み込み、それらを1つの大きなDataFrameに連結します。私はそれを理解することができませんでした。これが私がこれまでに持っているものです:
import glob
import pandas as pd
# get data file names
path =r'C:\DRO\DCL_rawdata_files'
filenames = glob.glob(path + "/*.csv")
dfs = []
for filename in filenames:
dfs.append(pd.read_csv(filename))
# Concatenate all data into one DataFrame
big_frame = pd.concat(dfs, ignore_index=True)
私はforループ内でいくつかの助けが必要だと思いますか???
すべてのcsv
ファイルに同じ列がある場合は、以下のコードを試すことができます。 csv
の最初の行を列名として割り当てることができるようにheader=0
を追加しました。
import pandas as pd
import glob
path = r'C:\DRO\DCL_rawdata_files' # use your path
all_files = glob.glob(path + "/*.csv")
li = []
for filename in all_files:
df = pd.read_csv(filename, index_col=None, header=0)
li.append(df)
frame = pd.concat(li, axis=0, ignore_index=True)
path = r'C:\DRO\DCL_rawdata_files' # use your path
all_files = glob.glob(os.path.join(path, "*.csv")) # advisable to use os.path.join as this makes concatenation OS independent
df_from_each_file = (pd.read_csv(f) for f in all_files)
concatenated_df = pd.concat(df_from_each_file, ignore_index=True)
# doesn't create a list, nor does it append to one
import glob, os
df = pd.concat(map(pd.read_csv, glob.glob(os.path.join('', "my_files*.csv"))))
Daskライブラリは複数のファイルからデータフレームを読み込むことができます。
>>> import dask.dataframe as dd
>>> df = dd.read_csv('data*.csv')
(出典: http://dask.pydata.org/en/latest/examples/dataframe-csv.html )
Daskデータフレームは、PandasデータフレームAPIのサブセットを実装しています。すべてのデータがメモリに収まる場合は、 df.compute()
を呼び出してデータフレームをPandasデータフレームに変換できます。
編集:私は https://stackoverflow.com/a/21232849/186078 に私の方法をグーグルしました。ただし最近では、データフレーム自体を反復的に操作するのではなく、numpyを使用してデータフレームに1回割り当てることが、より速いことがわかりました。
このページにアクセスしている人にこのアプローチを検討してもらいたいのですが、この巨大なコードをコメントとして添付して読みにくくしたくないと思います。
あなたはデータフレーム連結を本当にスピードアップするためにあなたはnumpyを利用することができます。
import os
import glob
import pandas as pd
import numpy as np
path = "my_dir_full_path"
allFiles = glob.glob(os.path.join(path,"*.csv"))
np_array_list = []
for file_ in allFiles:
df = pd.read_csv(file_,index_col=None, header=0)
np_array_list.append(df.as_matrix())
comb_np_array = np.vstack(np_array_list)
big_frame = pd.DataFrame(comb_np_array)
big_frame.columns = ["col1","col2"....]
タイミング統計:
total files :192
avg lines per file :8492
--approach 1 without numpy -- 8.248656988143921 seconds ---
total records old :1630571
--approach 2 with numpy -- 2.289292573928833 seconds ---
ここでの答えのほとんどすべては、不必要に複雑(グロブパターンマッチング)であるか、追加のサードパーティライブラリに依存しています。 Pandasとpython(すべてのバージョン)がすでに組み込まれているものすべてを使用して、2行でこれを実行できます。
いくつかのファイルの場合 - 1ライナー:
df = pd.concat(map(pd.read_csv, ['data/d1.csv', 'data/d2.csv','data/d3.csv']))
多くのファイルの場合:
from os import listdir
filepaths = [f for f in listdir("./data") if f.endswith('.csv')]
df = pd.concat(map(pd.read_csv, filepaths))
Dfを設定するこのパンダ行は3つのことを利用します。
pd.read_csv()
)に送ります。再帰的に検索したい場合 (Python 3.5以上)、あなたは次のことができます。
from glob import iglob
import pandas as pd
path = r'C:\user\your\path\**\*.csv'
all_rec = iglob(path, recursive=True)
dataframes = (pd.read_csv(f) for f in all_rec)
big_dataframe = pd.concat(dataframes, ignore_index=True)
最後の3行は1つの 単一行 で表すことができることに注意してください。
df = pd.concat((pd.read_csv(f) for f in iglob(path, recursive=True)), ignore_index=True)
**
のドキュメントはこちら にあります。また、リストの代わりに イテレータ を返すので、iglob
の代わりにglob
を使用しました。
編集:マルチプラットフォーム再帰関数:
上記を マルチプラットフォーム関数 (Linux、Windows、Mac)にラップすることができます。
df = read_df_rec('C:\user\your\path', *.csv)
これが関数です:
from glob import iglob
from os.path import join
import pandas as pd
def read_df_rec(path, fn_regex=r'*.csv'):
return pd.concat((pd.read_csv(f) for f in iglob(
join(path, '**', fn_regex), recursive=True)), ignore_index=True)
複数のcsvファイルが圧縮されている場合は、zipfileを使用してすべてを読み取り、以下のように連結することができます。
import zipfile
import numpy as np
import pandas as pd
ziptrain = zipfile.ZipFile('yourpath/yourfile.Zip')
train=[]
for f in range(0,len(ziptrain.namelist())):
if (f == 0):
train = pd.read_csv(ziptrain.open(ziptrain.namelist()[f]))
else:
my_df = pd.read_csv(ziptrain.open(ziptrain.namelist()[f]))
train = (pd.DataFrame(np.concatenate((train,my_df),axis=0),
columns=list(my_df.columns.values)))
@Sidの良い答えに基づいています。
連結する前に、csvファイルを中間辞書にロードして、ファイル名(dict_of_df['filename.csv']
形式)に基づいて各データセットにアクセスできます。このような辞書は、たとえば列名が揃っていない場合に、異種データ形式の問題を特定するのに役立ちます。
import os
import glob
import pandas
from collections import OrderedDict
path =r'C:\DRO\DCL_rawdata_files'
filenames = glob.glob(path + "/*.csv")
注:OrderedDict
は必要ありませんが、分析に役立つ可能性のあるファイルの順序を保持します。
dict_of_df = OrderedDict((f, pandas.read_csv(f)) for f in filenames)
pandas.concat(dict_of_df, sort=True)
キーはファイル名f
で、値はcsvファイルのデータフレームコンテンツです。 f
をディクショナリキーとして使用する代わりに、os.path.basename(f)
または他の os.path メソッドを使用して、ディクショナリ内のキーのサイズを小さい部分のみに減らすこともできます。それは関連しています。
私はこの方法がとてもエレガントだと感じました。
import pandas as pd
import os
big_frame = pd.DataFrame()
for file in os.listdir():
if file.endswith('.csv'):
df = pd.read_csv(file)
big_frame = big_frame.append(df, ignore_index=True)
1つのライナーでmap
を使用していますが、追加の引数を指定したい場合は、次のようにします。
import pandas as pd
import glob
import functools
df = pd.concat(map(functools.partial(pd.read_csv, sep='|', compressed=None),
glob.glob("data/*.csv")))
注:map
beそれ自体では、追加の引数を指定することはできません。
Read_csvで引数を使用することを可能にするリスト内包表記のもう1つのオンライナー。
df = pd.concat([pd.read_csv(f'dir/{f}') for f in os.listdir('dir') if f.endswith('.csv')])
名前のリストを作成せずに、2つ以上のcsv
をインポートします。
import glob
df = pd.concat(map(pd.read_csv, glob.glob('data/*.csv'))