根据文件名中的日期模式从目录中读取文件子集的更快和更节省内存的方法是啥?
Posted
技术标签:
【中文标题】根据文件名中的日期模式从目录中读取文件子集的更快和更节省内存的方法是啥?【英文标题】:What's a faster and more memory-efficient way to read_csv a subset of files from a directory based upon a date pattern in their filename?根据文件名中的日期模式从目录中读取文件子集的更快和更节省内存的方法是什么? 【发布时间】:2020-11-04 07:54:30 【问题描述】:我现在的代码:
cols = ['X','Y','Z','W','A']
path = r'/Desktop/files'
all_files = glob.glob(path + "/file*")
d_list = pd.date_range('2019-09-01','2020-09-09',freq='D').strftime("%Y-%m-%d").tolist()
list1 = []
for i in d_list:
for filename in all_files:
if i in filename:
df = pd.read_csv(filename,sep='|',usecols=cols)
list1.append(df)
data = pd.concat(list1, axis=0, ignore_index=True)
这段代码需要很长时间才能运行,我假设我没有足够的内存。 有没有其他方法可以让它更快? 如果有人知道我如何使用 dask.dataframe 以及是否有帮助,但还要保留变量的原始数据类型,请告诉我。
谢谢!
【问题讨论】:
d_list
和for i in d_list:
的目的是什么?您是否尝试遍历多个目录?如果是这样,那就不清楚了,看来你做错了。我的答案只针对一个文件夹。
d_list 是我感兴趣的日期列表,例如,名为“file_2018-12-01”的文件超出了我的日期范围,因此不应读取。
你可以通过首先创建一个列表来显着加快速度,因为这样你就不必遍历目录 10 次。无法从您的代码中看出文件名的模式是什么样的,但您可以执行 all_files = glob.glob(path + "/file*2019-09-0*")
之类的操作
【参考方案1】:
使用 dask 尝试以下操作:
import dask.dataframe as dd
#This is an example of a common pattern you could have for your files, so that you can loop through them one time rather than loop through a list of dates 10x.
all_files = glob.glob(r'/Desktop/files/file*2019-09-0*.csv')
df = dd.concat([dd.read_csv(f, sep='|', usecols=cols) for f in all_files])
#df1 = df.compute() #returns a pandas dataframe from the dask dataframe
Pandas 的语法基本相同:
import pandas as pd
all_files = glob.glob(r'/Desktop/files/file*2019-09-0*.csv')
df = pd.concat([pd.read_csv(f, sep='|', usecols=cols) for f in all_files])
【讨论】:
我尝试将您的代码与 dask 一起使用,但它不返回 df,您是否运行了此代码?它为你返回 df 了吗? @Mari 我编了文件路径,因为我不知道你的文件是什么样的。当你做print(all_files)
时,你看到了什么? @Mari 这段代码对我有用,我刚刚运行它。如果您想在作为 dask 数据帧读入后返回 pandas 数据帧,请使用 .compute()
例如df_new = df.compute()
然后df_new
而且,如果您想将其保留为 dask 数据框,则 dask 仅显示列标题和数据类型。它不会显示所有数据。以上是关于根据文件名中的日期模式从目录中读取文件子集的更快和更节省内存的方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何在读取前根据定义的模式读取 pyspark 中的镶木地板文件?