it-swarm.com.de

Importieren Sie mehrere csv-Dateien in pandas und verknüpfen Sie sie zu einem DataFrame

Ich möchte mehrere csv-Dateien aus einem Verzeichnis in pandas einlesen und zu einem großen DataFrame zusammenfassen. Ich konnte es jedoch nicht herausfinden. Folgendes habe ich bisher:

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)

Ich denke, ich brauche Hilfe in der for-Schleife?

281
jonas

Wenn Sie in allen csv Dateien die gleichen Spalten haben, können Sie den folgenden Code ausprobieren. Ich habe header=0 hinzugefügt, damit nach dem Lesen von csv die erste Zeile als Spaltenname zugewiesen werden kann.

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)
320
Gaurav Singh

Eine Alternative zu DarindaCoders Antwort :

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
244
Sid
import glob, os    
df = pd.concat(map(pd.read_csv, glob.glob(os.path.join('', "my_files*.csv"))))
43

Fast alle Antworten sind hier entweder unnötig komplex (Glob-Pattern-Matching) oder basieren auf zusätzlichen Bibliotheken von Drittanbietern. Sie können dies in 2 Zeilen tun, indem Sie alles verwenden, was Pandas und python (alle Versionen) bereits eingebaut haben.

Für ein paar Dateien - 1 Liner:

df = pd.concat(map(pd.read_csv, ['data/d1.csv', 'data/d2.csv','data/d3.csv']))

Für viele Dateien:

from os import listdir

filepaths = [f for f in listdir("./data") if f.endswith('.csv')]
df = pd.concat(map(pd.read_csv, filepaths))

Diese pandas Zeile, die den df einstellt, verwendet 3 Dinge:

  1. Pythons Map (function, iterable) sendet an die Funktion (die pd.read_csv()) die iterable (unsere Liste), die jedes csv-Element in Dateipfaden ist).
  2. Die Funktion read_csv () des Panda liest jede CSV-Datei wie gewohnt ein.
  3. Panda concat () bringt all diese unter eine df-Variable.
18
robmsmt

Die Dask-Bibliothek kann einen Datenrahmen aus mehreren Dateien lesen:

>>> import dask.dataframe as dd
>>> df = dd.read_csv('data*.csv')

(Quelle: http://dask.pydata.org/en/latest/examples/dataframe-csv.html )

Die Dask-Datenrahmen implementieren eine Teilmenge der Pandas-Datenrahmen-API. Wenn alle Daten in den Speicher passen, können Sie df.compute() aufrufen , um den Datenrahmen in einen Pandas Datenrahmen zu konvertieren.

18

Bearbeiten: Ich googelte meinen Weg in https://stackoverflow.com/a/21232849/186078 . In letzter Zeit finde ich es jedoch schneller, Manipulationen mit numpy durchzuführen und sie dann einmal einem Datenrahmen zuzuweisen, anstatt den Datenrahmen selbst iterativ zu manipulieren, und es scheint auch in dieser Lösung zu funktionieren.

Ich möchte aufrichtig, dass jeder, der diese Seite besucht, über diesen Ansatz nachdenkt, aber ich möchte diesen großen Teil des Codes nicht als Kommentar anfügen und ihn weniger lesbar machen.

Sie können numpy nutzen, um die Verkettung von Datenrahmen wirklich zu beschleunigen.

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"....]

Timing-Statistiken:

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 ---
12
SKG

Wenn Sie rekursiv suchen möchten ( Python 3.5 oder höher ), können Sie Folgendes tun:

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)

Beachten Sie, dass die drei letzten Zeilen in einer einzelnen Zeile ausgedrückt werden können:

df = pd.concat((pd.read_csv(f) for f in iglob(path, recursive=True)), ignore_index=True)

Sie finden die Dokumentation von **hier . Außerdem habe ich iglob anstelle von glob verwendet, da statt einer Liste ein Iterator zurückgegeben wird.



EDIT: Rekursive Multiplattform-Funktion:

Sie können das Obige in eine Multiplattform-Funktion (Linux, Windows, Mac) einbinden, so dass Sie Folgendes tun können:

df = read_df_rec('C:\user\your\path', *.csv)

Hier ist die Funktion:

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)
10
toto_tico

Wenn die mehreren CSV-Dateien komprimiert sind, können Sie mit zipfile alle Dateien lesen und wie folgt verknüpfen:

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)))
4
Nim J

Basierend auf der guten Antwort von @ Sid.

Vor dem Verketten können Sie csv-Dateien in ein Zwischenwörterbuch laden, das den Zugriff auf jeden Datensatz anhand des Dateinamens ermöglicht (in der Form dict_of_df['filename.csv']). Ein solches Wörterbuch kann Ihnen helfen, Probleme mit heterogenen Datenformaten zu identifizieren, wenn beispielsweise Spaltennamen nicht ausgerichtet sind.

Module importieren und Dateipfade suchen:

import os
import glob
import pandas
from collections import OrderedDict
path =r'C:\DRO\DCL_rawdata_files'
filenames = glob.glob(path + "/*.csv")

Hinweis: OrderedDict ist nicht erforderlich, behält jedoch die Reihenfolge der Dateien bei, die für die Analyse nützlich sein können.

Laden Sie CSV-Dateien in ein Wörterbuch. Dann verketten:

dict_of_df = OrderedDict((f, pandas.read_csv(f)) for f in filenames)
pandas.concat(dict_of_df, sort=True)

Schlüssel sind Dateinamen f und Werte sind der Datenrahmeninhalt von CSV-Dateien. Anstatt f als Wörterbuchschlüssel zu verwenden, können Sie auch os.path.basename(f) oder andere os.path -Methoden verwenden, um die Größe des Schlüssels im Wörterbuch nur auf den kleineren Teil zu reduzieren das ist relevant.

2
Paul Rougieux

ein Zeilenumbruch mit map, aber wenn Sie zusätzliche Argumente angeben möchten, können Sie Folgendes tun:

import pandas as pd
import glob
import functools

df = pd.concat(map(functools.partial(pd.read_csv, sep='|', compressed=None), 
                    glob.glob("data/*.csv")))

Hinweis: map be selbst lässt Sie keine zusätzlichen Argumente angeben.

2
muon

Einfach und schnell

Importieren Sie 2 oder mehr csv, ohne eine Liste von Namen erstellen zu müssen.

import glob

df = pd.concat(map(pd.read_csv, glob.glob('data/*.csv'))
2
MrFun

Ich fand diese Methode ziemlich elegant.

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)
2
Erfan

Ein weiterer Onliner mit Listenverständnis, der die Verwendung von Argumenten mit read_csv ermöglicht.

df = pd.concat([pd.read_csv(f'dir/{f}') for f in os.listdir('dir') if f.endswith('.csv')])
1
mjspier