2017-10-10 3 views
0

Ich versuche, einen Datenrahmen mit zwei Spalten aus 50 CSV-Dateien haben 5000 Zeilen und etwa 15 Spalten. Wenn ich versuche, es ohne die concat-Funktion auszuführen, hat es viel Speicher verbraucht und ich habe den Kill-Fehler bekommen. Jetzt zerstückele ich die Datenbank und verbinde sie dann. Das einzige Problem ist, dass, wenn ich die Chunks concat, behält es den Header für jeden Chunk und wenn ich head() für die df, es liefert mir die Kopfzeilen nur letzten Chunk. Und gibt es eine andere Möglichkeit, meinen Code noch schneller ausführen zu lassen, da ich gelesen habe, dass die Verwendung der concat-Funktion in for-loop ihn langsamer macht. Mein Code sieht wie folgt aus: -Umgang mit großen CSV-Dateien in Python3 mit Concat-Funktion

import os 
import csv 
import urllib.request as urllib 
import datetime as dt 
import pandas as pd 
import pandas_datareader.data as web 
import nsepy as nse 

def saveNiftySymbols(): 
    url = "https://www.nseindia.com/content/indices/ind_nifty50list.csv" 
# pretend to be a chrome 47 browser on a windows 10 machine 
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"} 
    req = urllib.Request(url, headers = headers) 
# open the url 
    x = urllib.urlopen(req) 
    sourceCode = x.read().decode('utf-8') 

    cr = csv.DictReader(sourceCode.splitlines()) 
    l = [row['Symbol'] for row in cr] 
    return l 

def symbolToPath(symbol, path='/Users/uditvashisht/Documents/udi_py/stocks/stock_dfs/'): 
    return os.path.join(path,"{}.csv".format(str(symbol))) 

def combinedNifty(l): 
    mainDf=pd.DataFrame() 

    for symbol in l: 
     chunks=pd.read_csv(symbolToPath(symbol),chunksize=10,usecols=['Date','Close'],index_col='Date',parse_dates=True) 
     df=pd.DataFrame() 
     for chunk in chunks: 
      df=pd.concat([chunk]) 

      df.rename(columns={'Close':symbol}, inplace=True) 


     if mainDf.empty: 
      mainDf = df 
     else: 
      mainDf = mainDf.join(df, how='outer') 

    print(mainDf.head()) 
    mainDf.to_csv('combinedNifty.csv') 


combinedNifty(saveNiftySymbols()) 

Antwort

0

Das einzige Problem ist, dass wenn ich die Stücke verketten, es den Header für jeden Block hält und wenn ich den Kopf drucken() für die df, es gibt mir die Kopfzeilen nur letzten Brocken

Dies liegt daran, was tatsächlich geschieht, ist nur Sie den letzten Brocken in Ihrem df haben. Wenn Sie ausführen, um diese Zeile:

df=pd.concat([chunk]) 

Sie sind sonst nur Ihre aktuellen Brocken mit nichts durch Verketten tatsächlich df neu zu definieren. Es ist effektiv, als würden Sie tun:

For chunk in chunks: 
    df = chunk 

Deshalb ist, wenn der Kopf() -Methode aufrufen werden Sie nur den letzten Brocken zu sehen. Stattdessen brauchen Sie keine for-Schleife, um Chunks zu verketten. Concat nimmt eine Liste von Datenrahmen als Argument und verkettet sie zusammen, so brauchen Sie nur zu tun:

df = pd.concat(chunks) 

Dies auch die Leistung verbessern sollte, weil es besser ist, einmal verketten mit einer Liste von vielen Datenrahmen anstatt das zu tun etwas wie df = pd.concat ([df, chunk]) in einer for-Schleife, das ist wahrscheinlich das, was Sie in Ihrem ursprünglichen Code tun wollten.

+0

Hallo, ich habe Ihre Methode verwendet, es half mir mit dem vollständigen Datenrahmen für einzelne Symbol in der Liste, anstelle von Chunks. Aber immer noch, wenn ich es mit dem obigen Code verwende, um Datenrahmen aus 50 csv-Dateien zu erstellen und sie dann zu verbinden. Ich bekomme Fehler getötet: 9. –

+0

Versuchen Sie den Ansatz [hier] (https://stackoverflow.com/questions/38089010/merge-a-list-of-pandas-dataframes), 'pd.merge' anstelle von Join zu verwenden, um alle Ihre Datenrahmen zusammenzuführen in einem Schritt außerhalb der for-Schleife, anstatt df.join wiederholt aufzurufen. Ich bin mir nicht sicher, ob Join das gleiche Problem wie concat hat, aber könnte Dinge verbessern. Machen Sie eine leere Liste und fügen Sie Ihre 'df' zu dieser Liste auf jedem' for symbol in l: 'Schleife, dann am Ende zusammenführen. Überprüfen Sie auch [diese Methode] (https://stackoverflow.com/questions/17557074/memory-error-when-using-pandas-read-csv), um Speicherfehler beim Lesen von CSVs zu reduzieren. –

+0

Auch ich bin mir nicht sicher, warum Sie so kleine Chunk-Größen verwenden, um die CSV zu verarbeiten. Siehe [diesen Beitrag] (https://stackoverflow.com/questions/25962114/how-to-read-a-6-gb-csv-file-with-pandas) bei der Verarbeitung großer csvs mit Chunks. Die Kommentare beschreiben auch den Vorteil, concat auf einer Liste statt mit einer for-Schleife aufzurufen. –

Verwandte Themen