2017-10-10 98 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循环的优点。 –