我刚刚开始学习Julia,我想在我的目录中阅读许多csv文件。我怎么能这样做?
我的目录中包含以下文件,我想读取trip_data_1到trip_data_12的所有文件。
“trip_data_1.csv” “trip_data_10.csv” “trip_data_11.csv” “trip_data_12.csv” “trip_data_2.csv” “trip_data_3.csv” “trip_data_4.csv” “trip_data_5.csv” “trip_data_6.csv” “trip_data_7.csv” “trip_data_8.csv” “trip_data_9.csv” “trip_fare_1.csv” “trip_fare_10.csv” “trip_fare_11.csv” “trip_fare_12.csv” “trip_fare_2.csv” “trip_fare_3.csv” “trip_fare_4.csv” “trip_fare_5.csv” “trip_fare_6.csv” “trip_fare_7.csv” “trip_fare_8.csv” “trip_fare_9.csv”
这就是我的尝试:
using DataFrames
df = readtable(filter!(r"^trip_data", readdir()))
但我得 MethodError:没有匹配readtable的方法(:: Array {String,1})
答案 0 :(得分:5)
你可以这样做:
reduce(vcat, map(readtable, filter(r"^trip_data", readdir())))
此处map
将readtable
应用于filter
匹配的每个文件名(此处不需要filter!
)并将所有结果数据框连接在一起(vcat
)。
可以使用mapreduce
:
mapreduce(readtable, vcat, filter(r"^trip_data", readdir()))
答案 1 :(得分:5)
在这种情况下,我非常喜欢.
broadcast
语法。
即。 df = readtable.(filter(r"^trip_data", readdir()))
会为您提供一系列数据框(@avysk是正确的,您可能需要filter
而不是filter!
。
如果您想要一个数据框,那么mapreduce
选项就是好的。
或者你可以:vcat(readtable.(filter(r"^trip_data", readdir()))
注意:所有这些都是问题的一般解决方案,我有一个将f
应用于x
的函数(方法),现在我想将它应用于许多x
因此,如果您收到另一个错误,表明您无法将函数直接应用于任何数组或集合,但您可以使用单个元素,那么map
,broadcast
/ .
&安培; list comprehensions是你的朋友!
答案 2 :(得分:3)
另一种方法(将连接移动到输入字符串级别而不是DataFrame级别)并使用Iterators
包:
readtable(IOBuffer(join(chain([drop((l for l in readlines(fn)),i>1?1:0) for (i,fn) in enumerate(filter!(r"^trip_data", readdir()))]...))))
这实际上可以节省一些时间和分配(在我的宠物示例中它确实如此),但这取决于输入文件的参数。
答案 3 :(得分:1)
这是一个使用Glob的解决方案,我认为它更具可读性:
using CSV, Glob, DataFrames
files = glob("trip_data_*.csv")
dfs = CSV.read.(files)
如另一个答案中所述,CSV.read.
(带有最后一个点)在files
数组上广播,并创建一个DataFrames数组。因此,最后一行等效于:
dfs = [CSV.read(file) for file in files]
最后,如果要串联所有文件,只需执行以下操作:
df = vcat(dfs...)
其中...
用于将可变数量的参数传递给函数。
答案 4 :(得分:0)
你也可以做一个简单的
files = filter(r".csv$", readdir(path))
df = vcat([readtable(f) for f in files])
作为后续行动,我对朱莉娅的CSV.read(file)
做了同样的事情,而且速度要慢得多。实际上不是阅读部分,而是采购部分:
source = CSV.Source(file)
CSV.Read(source)