使用concat函数在Python3中处理大型CSV文件

时间:2017-10-10 02:33:49

标签: python-3.x pandas chunks

我正在尝试构建一个包含50个csv文件的两列的数据框,这些文件有5000行,大约15列。当我尝试在不使用concat函数的情况下运行它时,它耗尽了大量内存并且我得到了kill错误。现在我正在分析数据库,然后进行相同的处理。唯一的问题是当我连接块时,它保留每个块的头部,当我为df打印head()时,它为我提供了只有最后一个块的头行。有没有其他方法可以让我的代码运行得更快,因为我已经读过在for循环中使用concat函数使它变得更慢。我的代码是这样的: -

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

1 个答案:

答案 0 :(得分:0)

  

唯一的问题是,当我连接块时,它会保留标题   对于每个块,当我为df打印head()时,它为我提供了   只有最后一个块的头行

这是因为实际发生的事情是你只有df中的最后一块。当你运行这一行时:

df=pd.concat([chunk])

实际上,你只是通过连接当前的chunk来重新定义df。它实际上就像你在做:

For chunk in chunks:
    df = chunk

这就是为什么在调用head()方法时你只能看到最后一个块。相反,您不需要for循环来连接块。 Concat将数据帧列表作为参数并将它们连接在一起,因此您只需要这样做:

df = pd.concat(chunks)

这也应该提高性能,因为最好使用许多数据帧列表连接一次,而不是在for循环中执行类似df = pd.concat([df,chunk])的操作,这可能就是你想要的用原始代码做。