我有六个 .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循环。制作一个文件名列表,然后一个接一个地读取它们,但我不想将它们合并在一起,所以我认为必须存在另一种方法。我一直在寻找它,但似乎所有问题都会导致连接最后读取的文件。
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
您可以使用列表来保存所有数据帧:
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
模块
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
有关数据分块的更多信息,请参阅此处
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 文件。请注意,这也一次仅加载一个文件。
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))