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

Handling large CSV files in Python3 using concat function

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

The only problem is that when I concat the chunks, it keeps the header for each chunk and when I print head() for the df, it provides me the head rows of only last chunk

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

df=pd.concat([chunk])

您实际上是在重新定义 df,仅将您的当前块与其他任何内容连接起来。它实际上就像你在做:

For chunk in chunks:
    df = chunk

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

df = pd.concat(chunks)

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