Dataframe 如何将.js文件读入数据帧

Dataframe 如何将.js文件读入数据帧,dataframe,file-io,julia,Dataframe,File Io,Julia,我有以下非标准文件,希望将其高效地读入数据帧,但不知道如何高效地处理它 m[mi++]="18.06.16 22:00:00|0;3;1;1667;49;49;12|0;17;3;2153;328;153;57|0;18;0;2165;284;156;53" m[mi++]="18.06.16 21:55:00|0;24;7;1667;306;306;61|0;21;4;2153;384;166;62|0;19;1;2165;368;185;62" m[mi++]="18.06.16 21:50

我有以下非标准文件,希望将其高效地读入数据帧,但不知道如何高效地处理它

m[mi++]="18.06.16 22:00:00|0;3;1;1667;49;49;12|0;17;3;2153;328;153;57|0;18;0;2165;284;156;53"
m[mi++]="18.06.16 21:55:00|0;24;7;1667;306;306;61|0;21;4;2153;384;166;62|0;19;1;2165;368;185;62"
m[mi++]="18.06.16 21:50:00|0;31;6;1667;394;349;62|0;32;6;2153;402;164;63|0;33;4;2165;380;171;63"
m[mi++]="18.06.16 21:45:00|11;50;19;1667;390;312;63|34;61;9;2153;410;166;63|19;60;8;2165;391;185;63"
m[mi++]="18.06.16 21:40:00|37;63;24;1666;387;313;63|55;80;12;2150;418;169;64|46;79;11;2163;398;186;63"
如果我已将此数据保存在文件a.js中,则以下代码有效:

b = readtable("a.js")
dat_5m = DataFrame(t=DateTime[], Pac_1=Float64[], Pdc_A1=Float64[], Pdc_B1=Float64[], Etot1=Float64[],
    U_A1=Float64[], U_B1=Float64[], T_1=Float64[], Pac_2=Float64[], Pdc_A2=Float64[], Pdc_B2=Float64[],
    Etot2=Float64[], U_A2=Float64[], U_B2=Float64[], T_2=Float64[], Pac_3=Float64[], Pdc_A3=Float64[],
    Pdc_B3=Float64[], Etot3=Float64[], U_A3=Float64[], U_B3=Float64[], T_3=Float64[])
for r in nrow(b):-1:1
   c = split(b[r,1], [';','|','=']);
   d = float(c[3:end])'
   t = DateTime(c[2], DateFormat("dd.mm.yy HH:MM:SS"))
   push!(dat_5m, [t d])
end
但我认为这是相当不公平的。有没有更有效的方法?

如果可能(IO允许),我建议先清理文件,删除
|
和任何时髦的
和前缀。然后你可以使用
CSV.jl
让你的生活更轻松

过程是:逐行读取,清洁每一行,然后使用
CSV
将其读回:

julia> using CSV

julia> open("b.js", "a") do new_file
           for line in readlines("a.js")
               line = replace(line, "m[mi++]=\"", "")
               # remove only trailing quote
               line = replace(line, r"\"$", "")
               line = replace(line, "|", ";")
               write(new_file, string(line, "\n"))
           end
       end


julia> b = CSV.read("b.js",
           delim = ";",
           header = false, # change this to a string vector to provide column names
           dateformat = "dd.mm.yy HH:MM:SS");

julia> # correct times to be in 2016
       b[:Column1] += Dates.Year(2000);

julia> head(b)
6×22 DataFrames.DataFrame. Omitted printing of 15 columns
│ Row │ Column1             │ Column2 │ Column3 │ Column4 │ Column5 │ Column6 │ Column7 │
├─────┼─────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ 1   │ 2016-06-18T22:00:00 │ 0       │ 3       │ 1       │ 1667    │ 49      │ 49      │
│ 2   │ 2016-06-18T21:55:00 │ 0       │ 24      │ 7       │ 1667    │ 306     │ 306     │
│ 3   │ 2016-06-18T21:50:00 │ 0       │ 31      │ 6       │ 1667    │ 394     │ 349     │
│ 4   │ 2016-06-18T21:45:00 │ 11      │ 50      │ 19      │ 1667    │ 390     │ 312     │
│ 5   │ 2016-06-18T21:40:00 │ 37      │ 63      │ 24      │ 1666    │ 387     │ 313     │
│ 6   │ 2016-06-18T22:00:00 │ 0       │ 3       │ 1       │ 1667    │ 49      │ 49      │
为了让过程更容易理解,我一步一步地清理了这里的行。如果你是正则表达式大师,你可能想在一行中完成

可能有更好的方法来处理2位数年份,因此如果有人知道如何修复,请编辑此答案或将其添加为注释。谢谢

编辑: 如果您想在不写入另一个文件的情况下执行相同的操作,下面是一个应用清理功能的方法,通过再次将
readlines
数组转换为
IOBuffer
来重用
CSV.read()

function cleaner(line)
    line = replace(line, "m[mi++]=\"", "")
    line = replace(line, r"\"$", "")
    line = replace(line, "|", ";")
    println(line)
    string(line, "\n")
end

c = CSV.read(
    Base.IOBuffer(
        string(cleaner.(readlines("a.js"))...)),
        delim = ";",
        header = false,
        dateformat = "dd.mm.yy HH:MM:SS");

c[:Column1] += Dates.Year(2000);

这会得到与其他解决方案相同的结果。

为什么不用
替换
,去掉起始位以获得一致的分隔符?然后你可以使用
CSV.jl
阅读它。我在博客上有一些关于如何使用该软件包的简单教程:我还认为预处理输入数据是好的。我按照你的提示做了,但对我来说并没有真正起作用:
b=readstring(a[2]);b=replace(b,“|”,“;”);b=replace(b,“m[mi++]=\”,”);CSV.read(b;delim=“;”)
还有什么提示吗?谢谢。不可能只创建一种临时文件,在其中存储数据,然后直接从中读取数据?我真的必须把它再次保存到磁盘上吗?你不必,但这是最简单的方法。这个文件对于这样的操作来说太大了吗?不,这是可能的,但是每天都有这样一个文件。。。已经有几千人了。好的,我总是可以覆盖同一个文件,但我认为另一种方式可能更优雅……用一种新的解决方案编辑我的答案,而不需要您编写新文件。不过,这可能会降低效率。我不确定。