Управление данными в DataFrame: как вычислить квадрат столбца - PullRequest
6 голосов
/ 09 июля 2020

Я хотел бы вычислить квадрат столбца A 1,2,3,4, обработать его с помощью других вычислений, сохранить его в столбце C

using CSV, DataFrames
df = DataFrame(A = 1:4, B = ["M", "F", "F", "M"])
df.C = ((((df.A./2).^2).*3.14)./1000)

Есть ли более простой способ записать его?

Ответы [ 2 ]

4 голосов
/ 09 июля 2020

Я не уверен, насколько короче вы хотели бы получить формулу, но вы можете написать:

df.C = @. (df.A / 2) ^ 2 * 3.14 / 1000

, чтобы не писать везде ..

Или вы можно использовать transform!, но он не короче (его преимущество в том, что вы можете использовать его в конвейере обработки, например, используя Pipe.jl):

transform!(df, :A => ByRow(a -> (a / 2) ^ 2 * 3.14 / 1000) => :C)
3 голосов
/ 09 июля 2020

Попробуйте следующее:

df.D = .5df.A .^2 * 0.00314

Объяснение:

  • требуется не так много скобок
  • умножение скаляра на вектор здесь так же хорошо, как и векторизация для краткости векторов (до двух примерно 100 элементов)

Простой тест с использованием BenchmarkTools:

julia> @btime $df.E = .5*$df.A .^2 * 0.00314;
  592.085 ns (9 allocations: 496 bytes)

julia> @btime $df.F = @. ($df.A / 2) ^ 2 * 0.00314;
  875.490 ns (11 allocations: 448 bytes)

Самая быстрая, однако, более длинная версия, где вы предоставляете информацию о типе @. (df.A::Vector{Int} / 2) ^ 2 * 0.00314 (снова это имеет значение для краткости DataFrame s и обратите внимание, что здесь должен существовать столбец Z, поэтому мы создаем его здесь):

julia> @btime begin $df.Z = Vector{Float64}(undef, nrow(df));@. $df.Z = ($df.A::Vector{Int} / 2.0) ^ 2.0 * 0.00314; end;
  162.564 ns (3 allocations: 208 bytes)
...