여러분, 여기에는 SH (1)에서 SH (200)까지 이름이 지정된 200 개의 개별 csv 파일이 있습니다. 단일 csv 파일로 병합하고 싶습니다. 어떻게하니?
여러분, 여기에는 SH (1)에서 SH (200)까지 이름이 지정된 200 개의 개별 csv 파일이 있습니다. 단일 csv 파일로 병합하고 싶습니다. 어떻게하니?
답변:
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()
f.__next__()
대신 사용할 수 있습니다 f.next()
.
with open
구문을 사용 .close()
하고 파일을 수동으로 처리하지 않아도됩니다.
f.next()
과 의 차이점은 무엇 f.__next__()
입니까? 전자를 사용하면 다음과 같은 결과를 얻었습니다'_io.TextIOWrapper' object has no attribute 'next'
fout.write(line)
내가 하기 전에 :if line[-1] != '\n': line += '\n'
왜 안돼 sed 1d sh*.csv > merged.csv
?
때로는 파이썬을 사용할 필요조차 없습니다!
사용하다 StackOverflow의 답변을 받아 당신이 추가 한 후이 코드를 실행하려는 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 )
fout=open("out.csv","a")
for num in range(1,201):
for line in open("sh"+str(num)+".csv"):
fout.write(line)
fout.close()
바구니에있는 다른 코드 예제를 살펴 보겠습니다.
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)
"병합"이 의미하는 바에 따라 다릅니다. 동일한 열이 있습니까? 헤더가 있습니까? 예를 들어, 모두 동일한 열이 있고 헤더가없는 경우 간단한 연결만으로도 충분합니다 (쓰기를 위해 대상 파일을 열고, 읽기 위해 각각을 여는 소스를 반복하고, 읽기 위해 열기 소스의 shutil.copyfileobj 를 사용 하여 쓰기 위해 열기 대상, 소스 닫기, 계속 반복- with
명령문을 사용 하여 대신 닫기를 수행하십시오). 열이 같지만 헤더도 readline
있는 경우 첫 번째 파일을 제외하고 각 소스 파일에이 파일 이 있어야합니다 . 첫 번째 파일을 열어서 대상으로 복사하기 전에 헤더 행을 건너 뜁니다.
CSV 파일이 모두 동일한 열을 가지고 있지 않다면 어떤 의미로 "병합"하는지 정의해야합니다 (예 : SQL JOIN? 또는 모두 동일한 수의 행이있는 경우 "수평"? 등). )-이 경우 당신이 의미하는 바를 추측하기가 어렵습니다.
병합 된 CSV가 Python에서 사용되는 경우를 사용하여 인수 glob
를 fileinput.input()
통해 전달할 파일 목록을 files
가져온 다음 csv
모듈을 사용하여 한 번에 모두 읽습니다.
디렉토리의 모든 파일을 결합하고 병합하는 것이 매우 쉽습니다.
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)
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 데이터 행이 있는지 여부에 관계없이 작동합니다. 또한이 코드를 실행하지는 않았지만 무엇을해야하는지에 대한 아이디어를 제공 할 것입니다.
@Adders를 만들고 나중에 @varun에 의해 개선 된 솔루션에 대해 약간의 개선을 구현하여 전체 병합 된 CSV를 기본 헤더 만 남겨 둡니다.
from glob import glob
filename = 'main.csv'
with open(filename, 'a') as singleFile:
first_csv = True
for csv in glob('*.csv'):
if csv == filename:
pass
else:
header = True
for line in open(csv, 'r'):
if first_csv and header:
singleFile.write(line)
first_csv = False
header = False
elif header:
header = False
else:
singleFile.write(line)
singleFile.close()
친애하는!!!
내장 csv
라이브러리 를 사용하기 만하면됩니다 . 이 솔루션은 다른 상위 투표 답변과 달리 일부 CSV 파일의 열 이름이나 헤더가 약간 다른 경우에도 작동합니다.
import csv
import glob
filenames = [i for i in glob.glob("SH*.csv")]
header_keys = []
merged_rows = []
for filename in filenames:
with open(filename) as f:
reader = csv.DictReader(f)
merged_rows.extend(list(reader))
header_keys.extend([key for key in reader.fieldnames if key not in header_keys])
with open("combined.csv", "w") as f:
w = csv.DictWriter(f, fieldnames=header_keys)
w.writeheader()
w.writerows(merged_rows)
병합 된 파일에는 header_keys
파일에서 찾을 수있는 가능한 모든 열 ( ) 이 포함됩니다 . 파일에없는 열은 공백 / 빈 상태로 렌더링되지만 파일의 나머지 데이터는 유지됩니다.
노트 :
csv
라이브러리를 계속 사용할 수 있지만 DictReader
& 를 사용하는 대신 DictWriter
기본 reader
& 으로 작업해야합니다.writer
.merged_rows
목록) 에 저장되므로 대용량 데이터를 처리 할 때 문제가 발생할 수 있습니다 .인코딩 문제가있는 사람들을 위해 @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()
다음은 스크립트입니다.
SH1.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())
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()
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 파일).
파일에 순서대로 번호가 지정되지 않은 경우 아래의 번거 로움없는 접근 방식을 사용하십시오. Windows 시스템의 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)
사용하기 쉬운 기능 :
def csv_merge(destination_path, *source_paths):
'''
Merges all csv files on source_paths to destination_path.
:param destination_path: Path of a single csv file, doesn't need to exist
:param source_paths: Paths of csv files to be merged into, needs to exist
:return: None
'''
with open(destination_path,"a") as dest_file:
with open(source_paths[0]) as src_file:
for src_line in src_file.read():
dest_file.write(src_line)
source_paths.pop(0)
for i in range(len(source_paths)):
with open(source_paths[i]) as src_file:
src_file.next()
for src_line in src_file:
dest_file.write(src_line)
import pandas as pd
import os
df = pd.read_csv("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data\\Sales_April_2019.csv")
files = [file for file in os.listdir("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data")
for file in files:
print(file)
all_data = pd.DataFrame()
for file in files:
df=pd.read_csv("e:\\data science\\kaggle assign\\monthly sales\\Pandas-Data-Science-Tasks-master\\SalesAnalysis\\Sales_Data\\"+file)
all_data = pd.concat([all_data,df])
all_data.head()