web-dev-qa-db-ja.com

200個のcsvファイルをPython

皆さん、ここにはSH(1)からSH(200)までの名前の200個のcsvファイルがあります。それらを単一のcsvファイルにマージしたいと思います。どうすればいいですか?

69
Chuck

Ghostdog74が言ったように、今回はヘッダー付き:

fout=open("out.csv","a")
# first file:
for line in open("sh1.csv"):
    fout.write(line)
# now the rest:    
for num in range(2,201):
    f = open("sh"+str(num)+".csv")
    f.next() # skip the header
    for line in f:
         fout.write(line)
    f.close() # not really needed
fout.close()
78
wisty

どうしてsed 1d sh*.csv > merged.csv

時にはPythonを使用する必要さえありません!

48
blinsay

受け入れられたStackOverflow answer を使用して、追加するcsvファイルのリストを作成し、次のコードを実行します。

import pandas as pd
combined_csv = pd.concat( [ pd.read_csv(f) for f in filenames ] )

また、単一のcsvファイルにエクスポートする場合は、これを使用します。

combined_csv.to_csv( "combined_csv.csv", index=False )
38
scottlittle
fout=open("out.csv","a")
for num in range(1,201):
    for line in open("sh"+str(num)+".csv"):
         fout.write(line)    
fout.close()
16
ghostdog74

バスケットにある別のコード例を見てみましょう

from glob import glob

with open('singleDataFile.csv', 'a') as singleFile:
    for csvFile in glob('*.csv'):
        for line in open(csvFile, 'r'):
            singleFile.write(line)
11
Norfeldt

「マージ」の意味によって異なります。同じ列がありますか?ヘッダーはありますか?たとえば、すべて同じ列があり、ヘッダーがない場合、単純な連結で十分です(書き込み用に宛先ファイルを開き、読み取り用にそれぞれを開くソースをループし、open shutil.copyfileobj を使用します) -for-reading source to open-for-write destination、close the source、looping-withステートメントを使用して、ユーザーに代わってクロージングを行います)。それらに同じ列があり、ヘッダーもある場合、ヘッダー行をスキップするために、宛先にコピーする前に読み取り用に開いた後、最初を除く各ソースファイルにreadlineが必要です。

CSVファイルがすべて同じ列を持たない場合、どのような意味でそれらを「マージ」するかを定義する必要があります(SQL JOINのように、またはすべてが同じ行数の場合は「水平に」などなど) )-その場合の意味を推測するのは困難です。

10
Alex Martelli

マージされたCSVをPythonで使用する場合、単に glob を使用して、渡すファイルのリストを取得します fileinput.input()files引数を介して、 csv モジュールを使用してすべてを一度に読み取ります。

実際には正しく動作しないため、上記のコードにわずかな変更を加えました。

次のようになります...

from glob import glob

with open('main.csv', 'a') as singleFile:
    for csv in glob('*.csv'):
        if csv == 'main.csv':
            pass
        else:
            for line in open(csv, 'r'):
                singleFile.write(line)
3
Adders

ディレクトリ内のすべてのファイルを非常に簡単に結合してマージする

import glob
import csv


# Open result file
with open('output.txt','wb') as fout:
    wout = csv.writer(fout,delimiter=',') 
    interesting_files = glob.glob("*.csv") 
    h = True
    for filename in interesting_files: 
        print 'Processing',filename 
        # Open and process file
        with open(filename,'rb') as fin:
            if h:
                h = False
            else:
                fin.next()#skip header
            for line in csv.reader(fin,delimiter=','):
                wout.writerow(line)
3
varun

Linux/macで作業している場合、これを行うことができます。

from subprocess import call
script="cat *.csv>merge.csv"
call(script,Shell=True)
2
sunny

Csvをインポートし、すべてのCSVファイルをループ処理してそれらをリストに読み込むことができます。次に、リストをディスクに書き戻します。

import csv

rows = []

for f in (file1, file2, ...):
    reader = csv.reader(open("f", "rb"))

    for row in reader:
        rows.append(row)

writer = csv.writer(open("some.csv", "wb"))
writer.writerows("\n".join(rows))

上記はエラー処理も開いているファイルも閉じないため、あまり堅牢ではありません。これは、個々のファイルにCSVデータの1つ以上の行があるかどうかに関係なく機能するはずです。また、私はこのコードを実行しませんでしたが、それはあなたに何をすべきかのアイデアを与えるはずです。

1
cnobile

Python3のwistyの答えを更新する

fout=open("out.csv","a")
# first file:
for line in open("sh1.csv"):
    fout.write(line)
# now the rest:    
for num in range(2,201):
    f = open("sh"+str(num)+".csv")
    next(f) # skip the header
    for line in f:
         fout.write(line)
    f.close() # not really needed
fout.close()
0
ishandutta2007

スクリプトは次のとおりです。

  • SH1.csvという名前のcsvファイルをSH200.csvに連結する
  • ヘッダーを保持する
import glob
import re

# Looking for filenames like 'SH1.csv' ... 'SH200.csv'
pattern = re.compile("^SH([1-9]|[1-9][0-9]|1[0-9][0-9]|200).csv$")
file_parts = [name for name in glob.glob('*.csv') if pattern.match(name)]

with open("file_merged.csv","wb") as file_merged:
    for (i, name) in enumerate(file_parts):
        with open(name, "rb") as file_part:
            if i != 0:
                next(file_part) # skip headers if not first file
            file_merged.write(file_part.read())
0
x0s

または、あなたはただすることができます

cat sh*.csv > merged.csv
0

@wistyがpython 3.xで動作すると言ったことを変更しました。エンコードの問題がある人のために、ハードコーディングを避けるためにosモジュールを使用します

import os 
def merge_all():
    dir = os.chdir('C:\python\data\\')
    fout = open("merged_files.csv", "ab")
    # first file:
    for line in open("file_1.csv",'rb'):
        fout.write(line)
    # now the rest:
    list = os.listdir(dir)
    number_files = len(list)
    for num in range(2, number_files):
        f = open("file_" + str(num) + ".csv", 'rb')
        f.__next__()  # skip the header
        for line in f:
            fout.write(line)
        f.close()  # not really needed
    fout.close()
0
Maryam Pashmi

ファイルに順番に番号が付けられていない場合は、以下の手間のかからない方法を使用してください:Python 3.6:

import pandas as pd
from glob import glob

interesting_files = glob("C:/temp/*.csv") # it grabs all the csv files from the directory you mention here

df_list = []
for filename in sorted(interesting_files):

df_list.append(pd.read_csv(filename))
full_df = pd.concat(df_list)

# save the final file in same/different directory:
full_df.to_csv("C:/temp/merged_pandas.csv", index=False)
0
Azadeh Feizpour

次のような2つのcsvファイルがあるとします。

csv1.csv:

id,name
1,Armin
2,Sven

csv2.csv:

id,place,year
1,Reykjavik,2017
2,Amsterdam,2018
3,Berlin,2019

そして、あなたはこのcsv3.csvのような結果にしたい:

id,name,place,year
1,Armin,Reykjavik,2017
2,Sven,Amsterdam,2018
3,,Berlin,2019

その後、次のスニペットを使用してそれを行うことができます。

import csv
import pandas as pd

# the file names
f1 = "csv1.csv"
f2 = "csv2.csv"
out_f = "csv3.csv"

# read the files
df1 = pd.read_csv(f1)
df2 = pd.read_csv(f2)

# get the keys
keys1 = list(df1)
keys2 = list(df2)

# merge both files
for idx, row in df2.iterrows():
    data = df1[df1['id'] == row['id']]

    # if row with such id does not exist, add the whole row
    if data.empty:
        next_idx = len(df1)
        for key in keys2:
            df1.at[next_idx, key] = df2.at[idx, key]

    # if row with such id exists, add only the missing keys with their values
    else:
        i = int(data.index[0])
        for key in keys2:
            if key not in keys1:
                df1.at[i, key] = df2.at[idx, key]

# save the merged files
df1.to_csv(out_f, index=False, encoding='utf-8', quotechar="", quoting=csv.QUOTE_NONE)

ループを使用すると、複数のファイルに対して同じ結果を得ることができます(200 csvファイル)。

0
tsveti_iko