Постройте еженедельные данные из DataFrame ежедневных данных - PullRequest
5 голосов
/ 17 июня 2020
• 1000 неделю и построить вместо этого? Самый простой способ добиться этого.

Ответы [ 3 ]

2 голосов
/ 17 июня 2020

Пакет TimeSeries предоставляет различные утилиты для работы с данными TimeSeries. В этом случае вы можете использовать collapse для преобразования ежедневных данных в еженедельные:

julia> using TimeSeries, DataFrames

julia> ta = TimeArray(df.date, df.posts)
1311×1 TimeArray{Int64,1,Date,Array{Int64,1}} 2016-10-19 to 2020-06-16
│            │ A     │
├────────────┼───────┤
│ 2016-10-19 │ 1     │
│ 2016-10-20 │ 2     │
│ 2016-10-21 │ 3     │
│ 2016-10-23 │ 4     │
...

julia> weekly = collapse(ta, week, last, sum)
192×1 TimeArray{Int64,1,Date,Array{Int64,1}} 2016-10-23 to 2020-06-16
│            │ A     │
├────────────┼───────┤
│ 2016-10-23 │ 10    │
│ 2016-10-28 │ 22    │
│ 2016-11-06 │ 34    │
...

julia> using Gadfly
julia> plot(DataFrame(weekly)[1:end-1,:], x=:timestamp, y=:A, Geom.line(), Guide.ylabel("Weekly sum of Posts"), Guide.xlabel("Week"))
1 голос
/ 17 июня 2020

Вот мое предложение, которое позволяет контролировать, какой день вы используете для начала недели (я использую здесь понедельник), а также устойчиво к отсутствующим данным (даты могут повторяться в наборе данных):

df.weekno = Dates.days.(df.date .- Date(2000, 1, 3)) .÷ 7
combine(groupby(df, :weekno), :val => sum)

Обратите внимание, что производительность при использовании Week в 3,5 раза выше:

julia> @btime transform($df,:date => (d->floor.(d,Week)) => :week);
  63.699 μs (68 allocations: 175.47 KiB)
julia> @btime transform($df,:date => (d->Dates.days.(d .- Date(2000, 1, 3)) .÷ 7) => :week);
  18.900 μs (74 allocations: 175.64 KiB)
1 голос
/ 17 июня 2020

в DataFrames вы можете использовать groupby с combine следующим образом:

julia> using Statistics, Dates, Pipe;
julia> df = DataFrame(date = range(Date(2000, 01, 01), Date(2020, 01, 01), step = Day(1)));
julia> df.val = rand(nrow(df));
julia> @pipe df |>
           transform(_,
               :date => ByRow(year) => :year,
               :date => ByRow(week) => :week # 1:52
           ) |>
           groupby(_, [:week, :year]) |>
           transform(_, :val => mean)

Если вам нужна скользящая средняя, ​​вы можете использовать следующую функцию

julia> function lagged_mean(x, b)
           map(1:length(x)) do i
               i < b ? missing : mean(@view x[i-b+1:i])
           end
       end

julia> lagged_mean(df.val, 7)

...