पायथन में 200 सीएसवी फ़ाइलों को मर्ज कैसे करें


83

दोस्तों, मेरे यहाँ SH (1) से SH (200) नाम की 200 अलग-अलग सीएसवी फाइलें हैं। मैं उन्हें एक एकल सीएसवी फ़ाइल में मर्ज करना चाहता हूं। मैं यह कैसे कर सकता हूं?


3
किस तरह से आप उनका विलय करेंगे? (
समसामयिक

6
आप उन्हें कैसे विलय करना चाहते हैं? CSV फ़ाइल की प्रत्येक पंक्ति एक पंक्ति है। इसलिए एक सरल विकल्प यह है कि सभी फाइलों को एक साथ मिलाया जाए।
जॉन-एरिक

प्रत्येक फ़ाइल में दो कॉलम होते हैं। मैं उन्हें लगातार दो कॉलम के साथ एक फ़ाइल में मर्ज करना चाहता हूं।
चक

1
@Chuck: आपकी टिप्पणियों में सभी प्रतिक्रियाओं (प्रश्न के लिए, और उत्तरों के लिए) और आपके प्रश्न को अपडेट करने के बारे में कैसे?
tumultous_rooster

2
इस सवाल का नाम "हाउ टू कॉन्कट ..." के बजाय "कैसे मर्ज करना है ..." होगा
कोलीड्रे

जवाबों:


95

जैसा कि 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()

11
आप f.__next__()इसके बजाय f.next()python3.x में उपयोग कर सकते हैं ।
tsveti_iko

5
बस एक ध्यान दें: एक with openवाक्यविन्यास का उपयोग कर सकता है और .close()फ़ाइलों को मैन्युअल रूप से उपयोग करने से बच सकता है।
फतहकिसी

2
क्या बीच का अंतर है f.next()और f.__next__()? जब मैं पूर्व का उपयोग करता हूं, तो मुझे मिला'_io.TextIOWrapper' object has no attribute 'next'
जेसन गोल

इससे पहले कि fout.write(line)मैं करता:if line[-1] != '\n': line += '\n'
shisui

65

तुम सिर्फ क्यों नहीं कर सकते sed 1d sh*.csv > merged.csv?

कभी-कभी आपको अजगर का उपयोग करने की आवश्यकता नहीं होती है!


21
खिड़कियों पर, C: \> copy * .csv मर्ज हो गया ।csv
हवाई

6
शीर्ष लेख की जानकारी को एक फ़ाइल से कॉपी करें: sed -n 1p some_file.csv> merged_file.csv सभी सभी फ़ाइलों से अंतिम पंक्ति की प्रतिलिपि बनाएँ: sed 1d * .csv >> merged_file.csv
behas

3
@blinsay यह प्रत्येक CSV फ़ाइल में हेडर को मर्ज किए गए फ़ाइल के साथ ही जोड़ता है।
मीना

5
पहले एक के बाद प्रत्येक बाद की फ़ाइल के लिए शीर्ष लेख की जानकारी की प्रतिलिपि बनाए बिना आप इस आदेश का उपयोग कैसे करते हैं? मुझे लगता है कि हेडर की जानकारी बार-बार पॉप अप हो रही है।
जो

2
यदि आपको शीर्ष लेख को निकालने की आवश्यकता नहीं है तो यह बहुत अच्छा है!
ब्लेयरग 23

51

Csv फ़ाइलों की एक सूची बनाने के लिए स्वीकृत StackOverflow उत्तर का उपयोग करें जिन्हें आप जोड़ना चाहते हैं और फिर इस कोड को चलाएं:

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

और यदि आप इसे एक एकल सीएसवी फ़ाइल में निर्यात करना चाहते हैं, तो इसका उपयोग करें:

combined_csv.to_csv( "combined_csv.csv", index=False )

@ wisty, @ एंडी, मान लें कि सभी फाइलों में प्रत्येक पंक्ति के शीर्षक हैं - कुछ पंक्तियाँ अलग-अलग शीर्षकों के साथ। प्रत्येक फ़ाइल में 2 कॉलम के लिए कोई हेडर नहीं। कोई कैसे विलीन हो सकता है, जैसे कि प्रत्येक फ़ाइल के लिए केवल एक कॉलम जोड़ा जाता है।
गैथाइड

फ़ाइल को कहाँ निर्यात किया जाता है?

@ dirtysocks45, मैंने इसे और अधिक स्पष्ट करने के लिए उत्तर बदल दिया।
स्कैटललैक्ट

सॉर्ट जोड़ें: fil_ames में f के लिए संयुक्त_केएसवी = pd.concat ([pd.read_csv (f)], सॉर्ट = गलत)
sailfish009

16
fout=open("out.csv","a")
for num in range(1,201):
    for line in open("sh"+str(num)+".csv"):
         fout.write(line)    
fout.close()

13

मैं टोकरी में एक और कोड उदाहरण के माध्यम से जा रहा हूँ

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)

2
@ और मैं स्टैकओवरफ्लो के बीच अंतर को देखने के लिए मुझे एक जवाब देने के लिए याद दिलाने में विफल रहा हूं और मुझे लोगों को उनकी प्रशंसा (वोटिंग करके) साझा करने की याद दिला रहा है अगर उन्हें मेरा जवाब उपयोगी लगा। मुझे पता है कि यह फेसबुक नहीं है और मैं एक शिकारी की तरह नहीं हूं ..
नोरफेल्ट

1
यह पहले से चर्चा की गई है , और हर बार इसे अस्वीकार्य माना गया है ।
एंडी

10

यह निर्भर करता है कि आप "विलय" से क्या मतलब है - क्या उनके पास समान कॉलम हैं? क्या उनके पास हेडर हैं? उदाहरण के लिए, यदि वे सभी समान कॉलम हैं, और कोई हेडर नहीं है, तो सरल संयोजन पर्याप्त है (लेखन के लिए गंतव्य फ़ाइल खोलें, पढ़ने के लिए प्रत्येक खोलने वाले स्रोतों पर लूप, ओपन-फॉर-रीडिंग स्रोत से shutil.copyfileobj का उपयोग करें ओपन-फॉर-राइटिंग डेस्टिनेशन, सोर्स बंद करें, लूपिंग रखें - withअपनी ओर से समापन करने के लिए स्टेटमेंट का उपयोग करें )। यदि उनके पास समान कॉलम हैं, लेकिन हेडर भी हैं, तो आपको readlineहेडर लाइन को छोड़ने के लिए गंतव्य पर कॉपी करने से पहले इसे पढ़ने के लिए खोलने के बाद, पहले के अलावा प्रत्येक स्रोत फ़ाइल पर आवश्यकता होगी ।

यदि CSV फ़ाइलों में सभी समान कॉलम नहीं होते हैं, तो आपको यह परिभाषित करने की आवश्यकता है कि आप उन्हें किस तरह "मर्ज" कर रहे हैं (जैसे कि SQL JOIN? या "क्षैतिज रूप से" यदि उन सभी में समान संख्या में लाइनें हैं?), आदि। ) - हमारे लिए यह अनुमान लगाना कठिन है कि उस मामले में आपका क्या मतलब है।


प्रत्येक फ़ाइल में हेडर के साथ दो कॉलम हैं। मैं उन्हें लगातार दो कॉलम के साथ एक फ़ाइल में मर्ज करना चाहता हूं।
चक

4

उपरोक्त कोड में थोड़ा सा बदलाव क्योंकि यह वास्तव में सही ढंग से काम नहीं करता है।

यह इस प्रकार होना चाहिए ...

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

यदि मर्ज किए गए CSV का उपयोग पायथन में किया जा रहा है , तो तर्क से globगुजरने के लिए फ़ाइलों की एक सूची प्राप्त करने के लिए बस का उपयोग करें , फिर सभी को एक बार में पढ़ने के लिए मॉड्यूल का उपयोग करें ।fileinput.input()filescsv


3

एक निर्देशिका में सभी फ़ाइलों को संयोजित करने और उन्हें मर्ज करने के लिए काफी आसान है

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

यदि आप linux / mac पर काम कर रहे हैं तो आप ऐसा कर सकते हैं।

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


1

आप 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

उस समाधान पर, जिसने @ विज्ञापन और बाद में @वरुण द्वारा सुधार किया, मैंने कुछ छोटे सुधार लागू किए, पूरे विलय किए गए सीएसवी को केवल मुख्य शीर्षक के साथ छोड़ दें:

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

सादर!!!


1

आप बस इन-बिल्ट 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 फ़ाइलों में कोई हेडर नहीं है तो यह काम नहीं करेगा। उस स्थिति में आप अभी भी csvपुस्तकालय का उपयोग कर सकते हैं , DictReaderऔर उपयोग करने के बजाय DictWriter, आपको मूल readerऔर के साथ काम करना होगा writer
  • यह उन मुद्दों में चल सकता है जब आप बड़े पैमाने पर डेटा के साथ काम कर रहे हैं क्योंकि सामग्री की संपूर्णता मेमोरी ( merged_rowsसूची) में संग्रहीत की जा रही है ।

0

मैंने संशोधित किया कि @wisty ने python 3.x के साथ काम करने के लिए क्या कहा, आप में से उन लोगों के लिए जिन्हें एन्कोडिंग की समस्या है, मैं हार्ड कोडिंग से बचने के लिए ओएस मॉड्यूल का भी उपयोग करता हूं

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

यहाँ एक स्क्रिप्ट है:

  • नाम 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())

0

पायथन 3 के लिए विस्टी के उत्तर को अपडेट करना

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

मान लीजिए कि आपके पास csvइनकी तरह 2 फाइलें हैं:

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 सीएसवी फाइलें)।


0

यदि फ़ाइलें क्रम में क्रमांकित नहीं हैं, तो नीचे झंझट-मुक्त दृष्टिकोण लें: विंडोज़ मशीन पर पायथन 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

एक आसान उपयोग समारोह:

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)

0
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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.