首页 > 解决方案 > 按时间戳绘制具有排序的 DataFrame 字段的多行

问题描述

我正在寻找一个优雅的解决方案来通过 Plots.jl 绘制线条,按时间戳排序

我希望每行代表不同年份的 closeAsk (Float64) 数据字段,根据时间戳年份判断,即 2002、2003 等。

因此,如果我们有从 2002 年到 2019 年的数据戳,如下例所示,我们应该在图表上有18条线。

julia> df2 = df[[:closeAsk, :time]]  
5000×2 DataFrame  
│ Row  │ closeAsk │ time                        │  
│      │ Float64  │ String                      │  
├──────┼──────────┼─────────────────────────────┤  
│ 1    │ 0.9949   │ 2002-11-28T22:00:00.000000Z │  
│ 2    │ 0.995    │ 2002-11-30T22:00:00.000000Z │  
⋮  
│ 4998 │ 1.13414  │ 2019-02-06T22:00:00.000000Z │  
│ 4999 │ 1.13244  │ 2019-02-07T22:00:00.000000Z │  
│ 5000 │ 1.13251  │ 2019-02-10T22:00:00.000000Z │  

我正在考虑的方式是使用理解来创建一组代表每年的 closeAsk 字段的 DataFrame,我们将其提供给 plot(x, y),其中 y 是那些被屠杀的 DataFrame 的数组。

提前致谢。

标签: dataframejulia

解决方案


像这样使用 StatsPlots.jl 应该是最简单的:

using StatsPlots, Dates
d = Date.(first.(df2.time, 10))
df2.year = year.(d)
df2.day = @. dayofyear(d) + ((!isleapyear(d)) & (month(d) > 2))
@df df2 plot(:day, :closeAsk, group=:year)

请注意,我创建:day的方式是在 x 轴上正确对齐月-日组合(控制在不同年份您可能有不同的交易日集合并在需要时进行闰年校正的事实)。

编辑

解释@. dayofyear(d) + ((!isleapyear(d)) & (month(d) > 2))

  1. @.广播此标志后的所有功能
  2. dayofyear(d):返回给定年份的天数;请注意,闰年有 366 天,其他年份有 365 天
  3. ((!isleapyear(d)) & (month(d) > 2)):如果年份不是闰年并且日期已过二月,则将 1 添加到天数,这样我们将所有年份标准化为 366 天(因此月日格式中的相同天数具有相同的天数 -请注意,我们必须从 3 月 1 日到 12 月 31 日移动 +1 日期)

这是一个简短的示例(请注意,2020 年是闰年,而 2021 年不是):

julia>  d = Date.(["2020-02-28", "2020-02-29", "2020-03-01", "2021-02-28", "2021-03-01"])
5-element Array{Date,1}:
 2020-02-28
 2020-02-29
 2020-03-01
 2021-02-28
 2021-03-01

julia> @. dayofyear(d) + ((!isleapyear(d)) & (month(d) > 2))
5-element Array{Int64,1}:
 59
 60
 61
 59
 61

这样,对于绘图上 x 轴上的相同值,您在所有年份中始终拥有同一天。


推荐阅读