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



我正试图从50个csv文件中构建一个包含两列的数据帧,该文件有5000行和约15列。当我尝试在不使用concat函数的情况下运行它时,它占用了大量内存,并出现了致命错误。现在,我正在对数据库进行分块,然后对其进行连接。唯一的问题是,当我插入块时,它会保留每个块的头,而当我为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())

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

这是因为实际发生的情况是,您的df中只有最后一块。当你运行这条线路时:

df=pd.concat([chunk])

实际上,您是在通过只连接当前块而不连接其他块来重新定义df。它实际上就像你在做:

For chunk in chunks:
df = chunk

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

df = pd.concat(chunks)

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

最新更新