#dataframe #group-by #julia #aggregate
#фрейм данных #группировать по #julia #агрегировать
Вопрос:
Я пытаюсь создать groupby sum в фрейме данных Julia со значениями Int и String
Например, df :
│ Row │ A │ B │ C │ D │
│ │ String │ String │ Int64 │ String │
├─────┼────────┼────────┼───────┼────────┤
│ 1 │ x1 │ a │ 12 │ green │
│ 2 │ x2 │ a │ 7 │ blue │
│ 3 │ x1 │ b │ 5 │ red │
│ 4 │ x2 │ a │ 4 │ blue │
│ 5 │ x1 │ b │ 9 │ yellow │
Чтобы сделать это в Python, команда может быть :
df_group = df.groupby(['A', 'B']).sum().reset_index()
Я получу следующий результат вывода с начальными метками столбцов :
A B C
0 x1 a 12
1 x1 b 14
2 x2 a 11
Я хотел бы сделать то же самое в Julia. Я пробовал этот способ, безуспешно :
df_group = aggregate(df, ["A", "B"], sum)
Ошибка метода: нет соответствия метода (::String, ::String)
Есть ли у вас какие-либо идеи о том, как это сделать в Julia?
Ответ №1:
Попробуйте (на самом деле вместо нестроковых столбцов, вероятно, вам нужны числовые столбцы):
numcols = names(df, findall(x -> eltype(x) <: Number, eachcol(df)))
combine(groupby(df, ["A", "B"]), numcols .=> sum .=> numcols)
и если вы хотите разрешить missing
значения (и пропустить их при выполнении суммирования), то:
numcols = names(df, findall(x -> eltype(x) <: Union{Missing,Number}, eachcol(df)))
combine(groupby(df, ["A", "B"]), numcols .=> sum∘skipmissing .=> numcols)
Комментарии:
1. Спасибо за ответ. На практике в моем реальном фрейме данных много столбцов для суммирования ( 100). Поэтому я хотел бы найти более общий способ сделать. Возможно ли сделать сумму по всем нестроковым столбцам?
2. Это возможно на master (так что оно будет доступно в версии 0.22). Я обновлю ответ рекомендацией, которую можно использовать сейчас.
Ответ №2:
Фреймы данных Julia поддерживают логику разделения-применения-объединения, аналогичную pandas, поэтому агрегирование выглядит следующим образом
using DataFrames
df = DataFrame(:A => ["x1", "x2", "x1", "x2", "x1"],
:B => ["a", "a", "b", "a", "b"],
:C => [12, 7, 5, 4, 9],
:D => ["green", "blue", "red", "blue", "yellow"])
gdf = groupby(df, [:A, :B])
combine(gdf, :C => sum)
с результатом
julia> combine(gdf, :C => sum)
3×3 DataFrame
│ Row │ A │ B │ C_sum │
│ │ String │ String │ Int64 │
├─────┼────────┼────────┼───────┤
│ 1 │ x1 │ a │ 12 │
│ 2 │ x2 │ a │ 11 │
│ 3 │ x1 │ b │ 14 │
Вы можете пропустить создание gdf
с помощью Pipe.jl или подчеркивания.jl
using Underscores
@_ groupby(df, [:A, :B]) |> combine(__, :C => sum)
Вы можете присвоить имя новому столбцу со следующим синтаксисом
julia> @_ groupby(df, [:A, :B]) |> combine(__, :C => sum => :C)
3×3 DataFrame
│ Row │ A │ B │ C │
│ │ String │ String │ Int64 │
├─────┼────────┼────────┼───────┤
│ 1 │ x1 │ a │ 12 │
│ 2 │ x2 │ a │ 11 │
│ 3 │ x1 │ b │ 14 │
Комментарии:
1. Спасибо за ваш ответ.
2. что, если я хочу выполнить групповую сумму и подсчитать в одной строке?