1

我正在尝试从文件夹中读取所有文件并尝试根据文件名创建文件名变量

我正在使用下面的代码来做到这一点。但我无法添加让我知道文件名的变量 -

using DataFrame
using Queryverse
using VegaLite
using Statistics
using CSV
using Glob

path = "D:\\Udemy\\FInancial_Engineering_Lazy_Programmer\\Yfinance_Data"
files = glob("*.csv", path)

df_com = DataFrame()
for file in files
    df = CSV.File(file)
    df[:filename] = first(split(last(split(file, "\\")),"."))
    append!(df_com, df)
end

我收到以下错误 -

ERROR: ArgumentError: invalid index: :filename of type Symbol
Stacktrace:
 [1] to_index(i::Symbol)
   @ Base .\indices.jl:300
 [2] to_index(A::CSV.File{false}, i::Symbol)
   @ Base .\indices.jl:277
 [3] to_indices
   @ .\indices.jl:333 [inlined]
 [4] to_indices
   @ .\indices.jl:325 [inlined]
 [5] setindex!(A::CSV.File{false}, v::Tuple{SubString{String}, Vector{Symbol}}, I::Symbol)
   @ Base .\abstractarray.jl:1267
 [6] top-level scope
   @ .\REPL[161]:3

创建文件名没有问题,但是将其添加到数据框时有问题。下面的代码工作正常并提供文件名,但无法将其添加为变量

for file in files
    println(first(split(last(split(file, "\\")),".")))
end

你能帮忙吗?

4

1 回答 1

1

这是最简洁的方法:

reduce(vcat,
       CSV.read.(files, DataFrame),
       source=:filename => chop.(basename.(files), tail=4))

现在,让我在您的代码中添加一些注释,希望它们对您有所帮助:

  • split(file, "\\")不推荐,因为它只能在 Windows 上运行,最好basename在所有操作系统上使用它;
  • usingfirst(split(your_filename,"."))不正确,因为如果您的文件名中包含多个.,则会产生错误的结果;chop如您所知,最后四个字符更干净.csv
  • CSV.File(file)不产生DataFrame物体;这就是后来df[:filename] = first(split(last(split(file, "\\")),"."))失败的原因;更好地用于CSV.read(file, DataFrame)有效地创建数据框,在这种情况下,您可以例如添加这样的列df.filename= first(split(last(split(file, "\")),"."))`
  • 更改了代码上面的代码就可以了,但是 usingvcat比重复调用更有效append!,因为vcat它针对合并多个数据帧进行了优化,该reduce(vcat, ...)部分确保您可以传递数据帧的向量(而不必列出它们);
  • vcat最后, over的一个好处append!是您不必:filename手动创建列,因为vcat支持source关键字参数来处理您的用例。

我希望这些提示可以帮助您总体上使用 DataFrames.jl。

于 2021-08-29T08:14:58.380 回答