对 pandas 中的多个 .csv 文件应用相同的操作

问题描述 投票:0回答:5

我有六个 .csv 文件。它们的整体尺寸约为 4gig。我需要清理每个数据并对其进行一些数据分析任务。这些操作对于所有帧都是相同的。 这是我阅读它们的代码。

#df = pd.read_csv(r"yellow_tripdata_2018-01.csv")
#df = pd.read_csv(r"yellow_tripdata_2018-02.csv")
#df = pd.read_csv(r"yellow_tripdata_2018-03.csv")
#df = pd.read_csv(r"yellow_tripdata_2018-04.csv")
#df = pd.read_csv(r"yellow_tripdata_2018-05.csv")
df = pd.read_csv(r"yellow_tripdata_2018-06.csv")

每次运行内核时,我都会激活要读取的文件之一。 我正在寻找一种更优雅的方式来做到这一点。我想过做一个for循环。制作一个文件名列表,然后一个接一个地读取它们,但我不想将它们合并在一起,所以我认为必须存在另一种方法。我一直在寻找它,但似乎所有问题都会导致连接最后读取的文件。

python pandas csv data-analysis
5个回答
3
投票

像这样使用
for
format
。我每天都用这个:

number_of_files = 6

for i in range(1, number_of_files+1):
    df = pd.read_csv("yellow_tripdata_2018-0{}.csv".format(i)))

    #your code here, do analysis and then the loop will return and read the next dataframe

3
投票

您可以使用列表来保存所有数据帧:

number_of_files = 6
dfs = []

for file_num in range(len(number_of_files)):
    dfs.append(pd.read_csv(f"yellow_tripdata_2018-0{file_num}.csv")) #I use Python 3.6, so I'm used to f-strings now. If you're using Python <3.6 use .format()

然后要获取某个数据帧,请使用:

df1 = dfs[0]

编辑:

当您试图避免将所有这些加载到内存中时,我会诉诸流式传输它们。尝试将 for 循环更改为如下所示:

for file_num in range(len(number_of_files)):
    with open(f"yellow_tripdata_2018-0{file_num}.csv", 'wb') as f:
        dfs.append(csv.reader(iter(f.readline, '')))

然后只需使用 for 循环

dfs[n]
next(dfs[n])
将每一行读入内存。

附注

您可能需要多线程来同时迭代每个线程。

加载/编辑/保存:

- 使用csv模块



好吧,所以我做了很多研究,Python 的 

csv

模块确实一次加载一行,它很可能是在我们打开它的模式下。

(解释了 
here 如果您不想使用

Pandas

(哪个分块可能确实是答案,只需将其实现到@seralouk的答案中),否则,那么是的!在我看来,这下面将是最好的方法,我们只需要改变一些事情。 number_of_files = 6 filename = "yellow_tripdata_2018-{}.csv" for file_num in range(number_of_files): #notice I'm opening the original file as f in mode 'r' for read only #and the new file as nf in mode 'a' for append with open(filename.format(str(file_num).zfill(2)), 'r') as f, open(filename.format((str(file_num)+"-new").zfill(2)), 'a') as nf: #initialize the writer before looping every line w = csv.writer(nf) for row in csv.reader(f): #do your "data cleaning" (THIS IS PER-LINE REMEMBER) #save to file w.writerow(row)

注:

您可能需要考虑使用

DictReader

和/或 DictWriter,我更喜欢它们而不是普通的阅读器/编写器,因为我发现它们更容易理解。

Pandas 方法

- 使用块

请阅读这个答案

- 如果您想放弃我的 csv 方法并坚持使用 Pandas :) 从字面上看,这似乎与您的问题相同,答案就是您所要求的。 基本上,Panda 允许您将文件部分加载为块,执行任何更改,然后您可以将这些块写入新文件。下面主要来自这个答案,但我自己在文档中做了更多阅读

number_of_files = 6 chunksize = 500 #find the chunksize that works best for you filename = "yellow_tripdata_2018-{}.csv" for file_num in range(number_of_files): for chunk in pd.read_csv(filename.format(str(file_num).zfill(2))chunksize=ch) # Do your data cleaning chunk.to_csv(filename.format((str(file_num)+"-new").zfill(2)), mode='a') #see again we're doing it in append mode so it creates the file in chunks

有关数据分块的更多信息,请参阅
此处

,对于像您这样因这些内存问题而头痛的人来说,这是一本很好的读物。


2
投票
glob.glob

获取所有具有相似名称的文件:

import glob
files = glob.glob("yellow_tripdata_2018-0?.csv")
for f in files:
    df = pd.read_csv(f)
    # manipulate df
    df.to_csv(f)

这将匹配 
yellow_tripdata_2018-0<any one character>.csv

。您还可以使用

yellow_tripdata_2018-0*.csv
来匹配
yellow_tripdata_2018-0<anything>.csv
甚至
yellow_tripdata_*.csv
来匹配以
yellow_tripdata
开头的所有 csv 文件。
请注意,这也一次仅加载一个文件。


0
投票

samplefiles = os.listdir(filepath) for filename in samplefiles: df = pd.read_csv(filename)

其中 filepath 是包含多个 csv 的目录?

或者更改文件名的循环:

for i in range(1, 7): df = pd.read_csv(r"yellow_tripdata_2018-0%s.csv") % ( str(i))



0
投票
© www.soinside.com 2019 - 2024. All rights reserved.