2017-10-10 87 views
0

我想構建一個數據幀,其中有兩列,從50個CSV文件有5000行,大約有15列。當我嘗試運行它而不使用concat函數時,它耗盡了大量內存,並且出現了kill錯誤。現在,我正在分解數據庫,然後將其相同。唯一的問題是,當我連接塊時,它會保留每個塊的標題,並且當我爲df打印head()時,它僅爲最後一個塊的頭部行提供了我。還有什麼其他的方式可以讓我的代碼運行得更快,因爲我已經讀過使用for循環中的concat函數使其更慢。我的代碼是這樣的: -使用concat函數處理Python3中的大型CSV文件

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

回答

0

唯一的問題是,當我Concat的大塊,它使頭 對於每個大塊,當我爲DF打印頭(),它提供了我只有最後一個大塊的 頭列

這是因爲什麼是真正發生的事情是,你只需要在你的DF最後一個大塊。當你運行該行:

df=pd.concat([chunk]) 

你是通過連接只有你沒有別的當前塊實際上重新定義DF。它是有效的,如果你是這樣做的:

For chunk in chunks: 
    df = chunk 

正在調用頭()方法,你只看到這最後一塊時,爲什麼。相反,您不需要for循環來連接塊。的毗連需要dataframes作爲參數列表並連接在一起,所以你只需要做到:

df = pd.concat(chunks) 

這也應該提高性能,因爲它是更好地與許多dataframes的列表Concat的一次,而不是做像for循環中的df = pd.concat([df,chunk]),這可能是您在原始代碼中執行的操作。

+0

嗨,我用你的方法,它幫助我獲取列表中的單個符號的完整數據框,而不是塊。但是,如果我使用上面的代碼來創建50個csv文件的數據幀,然後加入它們。我遇到錯誤:9。 –

+0

嘗試使用[here](此處)(https://stackoverflow.com/questions/38089010/merge-a-list-of-pandas-dataframes)使用'pd.merge'而不是join來合併所有數據框在for循環之外,而不是重複調用df.join。我不確定join是否與concat具有相同的問題,但可能會改進一些事情。製作一個空列表並將'df'追加到每個''for'循環中的符號列表中,然後在末尾合併。還要檢查[此方法](https://stackoverflow.com/questions/17557074/memory-error-when-using-pandas-read-csv)以減少讀取csv時的內存錯誤。 –

+0

另外,我不確定爲什麼你使用這樣的小塊大小來處理csv。查看[這篇文章](https://stackoverflow.com/questions/25962114/how-to-read-a-6-gb-csv-file-with-pandas)處理大塊csv的塊。這些註釋還描述了在列表中調用concat而不是使用for循環的優點。 –