# DataFrame groupby-aggregate strategy

**URL:** https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156
**Category:** General Usage
**Tags:** question
**Created:** [June 27, 2020, 2:12pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156 "2020-06-27T14:12:13Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![POKIN\_CHAN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pokin_chan/32/9309_2.png) [@POKIN\_CHAN](https://discourse.julialang.org/u/POKIN_CHAN)
#### Post date: [June 27, 2020, 2:12pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156/1 "2020-06-27T14:12:14Z")

</div>

Python:

```julia
df.groupby(["Z"])["A","B"].agg({"A":"max"})

```

I want to groupby “Z” column and take the maximum of “A” in each group. Values of Column “B”  
is the row when A is max.

I have used the following way but it is not the result I want.

```julia
combine(groupby(df,:Z),:A=>maximum=>:A,:B=>:B)

```

May I know the Julia way to do this? Thanks

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [June 27, 2020, 2:44pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156/2 "2020-06-27T14:44:46Z")

</div>

depending on what’s your expected behavior,

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/c/1ce064a299a348ed18fb90c7e510675f4813c738.png)

---

<div class="post-metadata">

### Author: ![POKIN\_CHAN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pokin_chan/32/9309_2.png) [@POKIN\_CHAN](https://discourse.julialang.org/u/POKIN_CHAN)
#### Post date: [June 27, 2020, 2:55pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156/4 "2020-06-27T14:55:09Z")

</div>

I do not withdraw this post.

---

<div class="post-metadata">

### Author: ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)
#### Post date: [June 27, 2020, 6:44pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156/5 "2020-06-27T18:44:25Z")

</div>

> [@POKIN\_CHAN](#):
>
> groupby “Z” column and take the maximum of “A” in each group. Values of Column “B”is the row when A is max.

The way I read his question the answer from jling does not seem right. But maybe I misunderstood.

maybe df3 in my code below is what the original poster wants

```julia
using Random 
using DataFrames 
Random.seed!(2)

df=DataFrame(rand(16,3))
rename!(df,[:A,:B,:Z])
df.Z .= round.(df.Z)

df2=combine(groupby(df,:Z),:A=>maximum=>:A)
df3=leftjoin(df2,df,on=[:A,:Z])
disallowmissing!(df3)

df4=combine(groupby(df,:Z),:A=>maximum=>:A,:B=>first=>:B)

isequal(df4,df3)

```

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [June 27, 2020, 7:29pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156/6 "2020-06-27T19:29:39Z")

</div>

I think I read the question the same way as you - however I was surprised that pandas would include the values of the other rows when using the aggregation function OP gave, and it looks like it doesn’t:

```julia
>>> df = pd.DataFrame({"a": [8, 2, 3, 1, 9, 3], "b": [11, 12, 13, 14, 15, 16], "c": ['a', 'a', 'a', 'b', 'b', 'b']})
>>> df
   a b c
0 8 11 a
1 2 12 a
2 3 13 a
3 1 14 b
4 9 15 b
5 3 16 b
>>> df.groupby(["c"])["a","b"].agg({"a":"max"})
<stdin>:1: FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead.
   a    
   a b
c       
a 8 13
b 9 16

```

so here it looks like you just get `last` for column `b`, irrespective of where `maximum(a)` is actually located - in which case this could be replicated by using `:B => last => :B` in DataFrames.jl

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [June 27, 2020, 7:45pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156/7 "2020-06-27T19:45:08Z")

</div>

Isn’t there another way without using a join?  
For example getting the index of the (A) maximum (instead of the maximum itself) and then use that index to retrieve the (A) maximum and also B.

---

<div class="post-metadata">

### Author: ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)
#### Post date: [June 27, 2020, 8:00pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156/8 "2020-06-27T20:00:58Z")

</div>

If I understand your problem correctly this is the way to do it. If you want to get the first maximum write:

```julia
combine(sdf -> sdf[argmax(sdf.a), [;a, :b]], groupby(df, :c))

```

and if you want all rows:

```julia
combine(sdf -> sdf[findall(==maximum(sdf.a), sdf.a), [;a, :b]], groupby(df, :c))

```

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [June 27, 2020, 8:16pm UTC](https://discourse.julialang.org/t/dataframe-groupby-aggregate-strategy/42156/9 "2020-06-27T20:16:11Z")

</div>

@bkamins also gave a great solution on Slack which I’ll add here so it doesn’t get swallowed by the Slack memory hole (as I’m sure I’ll be looking for this at some point in the near future):

```julia
julia> df = DataFrame(a = [8, 2, 3, 1, 9, 3], b = [11, 12, 13, 14, 15, 16], c = ['a', 'a', 'a', 'b', 'b', 'b'])
6×3 DataFrame
│ Row │ a │ b │ c │
│ │ Int64 │ Int64 │ Char │
├─────┼───────┼───────┼──────┤
│ 1 │ 8 │ 11 │ 'a' │
│ 2 │ 2 │ 12 │ 'a' │
│ 3 │ 3 │ 13 │ 'a' │
│ 4 │ 1 │ 14 │ 'b' │
│ 5 │ 9 │ 15 │ 'b' │
│ 6 │ 3 │ 16 │ 'b' │

julia> combine(groupby(df, :c), :a => maximum => :a, [:a, :b] => ((a,b) -> b[argmax(a)]) => :b)
2×3 DataFrame
│ Row │ c │ a │ b │
│ │ Char │ Int64 │ Int64 │
├─────┼──────┼───────┼───────┤
│ 1 │ 'a' │ 8 │ 11 │
│ 2 │ 'b' │ 9 │ 15 │

```

so by passing `[:a, :b]` to the `combine` call we can create a two argument anonymous function
