# How would I divide each row of a Julia dataframe by that rows maximum and return a new dataframe

**URL:** <https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597>\
**Category:** General Usage\
**Created:** [February 13, 2020, 6:41pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597 "2020-02-13T18:41:12Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Julia1](https://avatars.discourse-cdn.com/v4/letter/j/db5fbb/32.png) [@Julia1](https://discourse.julialang.org/u/Julia1)\
**Post date:** [February 13, 2020, 6:41pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/1 "2020-02-13T18:41:12Z")

</div>

Hi,

I’ve been looking around and messing with map, eachrow and different things but I haven’t been able to figure it out.

Essentially, if I have a N x M dataframe, I want to return a new N x M dataframe, except each value in the new dataframe is each value in the old dataframe divided by the maximum of the row it originally sits in the old dataframe.

For a 1 row dataframe of [2,4,6] it should return [.33,.66,1].

But in my use case mapped to a dataframe with many rows.

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [February 13, 2020, 6:51pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/2 "2020-02-13T18:51:51Z")

</div>

Probably not the most efficient solution:

```julia
df = DataFrame(a = rand(1:10, 3), b = rand(1:10, 3), c=rand(1:10, 3))
dfn = DataFrame(Float64, 0, 3) ## create a new dataframe with same number of columns
for r in eachrow(df)
    m = collect(r) ./ maximum(r)
    push!(dfn, m)
end

```

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [February 13, 2020, 6:53pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/3 "2020-02-13T18:53:51Z")

</div>

Have you tried

```julia
df ./ maximum.(eachrow(df))

```

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [February 13, 2020, 8:47pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/4 "2020-02-13T20:47:43Z")

</div>

May be it is possible to use `Matrix` instead of DataFrame? Rectangular matrix, filled with the values of the same type it’s, well, matrix.

---

<div class="post-metadata">

**Author:** ![Julia1](https://avatars.discourse-cdn.com/v4/letter/j/db5fbb/32.png) [@Julia1](https://discourse.julialang.org/u/Julia1)\
**Post date:** [February 14, 2020, 12:18am UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/5 "2020-02-14T00:18:53Z")

</div>

Yeah dataframe eachrow is taking too long damn. How would I do this with a Matrix? There isn’t a eachrow method

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [February 14, 2020, 12:40am UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/6 "2020-02-14T00:40:15Z")

</div>

There is an `eachrow` function for matrices. What version of Julia are you using?

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [February 14, 2020, 8:53am UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/7 "2020-02-14T08:53:41Z")

</div>

The `eachrow` version seems slow. Try the second version below:

```julia
julia> foo(df) = df ./ maximum.(eachrow(df));

julia> bar(df) = df ./ [maximum(df[i,:]) for i in 1:size(df,1)];

```

Performance test:

```julia
julia> df = DataFrame([Symbol("c$i") => rand(1000) for i in 1:100]...);

julia> size(df)
(1000, 100)

julia> @btime foo($df);
  5.139 s (55639946 allocations: 1003.91 MiB)

julia> @btime bar($df);
  41.489 ms (555946 allocations: 10.83 MiB)

```

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [February 14, 2020, 9:37am UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/8 "2020-02-14T09:37:26Z")

</div>

I suppose it can be golf coded, but generally it can be something like this

```julia
m = rand(1000, 100)
function baz!(m)
    for i in axes(m, 1)
        @views m[i, :] .= m[i, :] ./ maximum(m[i, :])
    end
end

@btime baz!($m) # 386.500 μs (3000 allocations: 140.63 KiB)

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 14, 2020, 4:00pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/9 "2020-02-14T16:00:37Z")

</div>

```julia
function fasterbaz!(m)
    m ./= maximum(m; dims = 2)
end

```

```julia
@btime fasterbaz!($m);
  181.505 μs (22 allocations: 8.52 KiB)

```

Interestingly, my non-allocating version is slower, probably because it’s accessing m’s memory in non-optimal order:

```julia
function fasterbaz2!(m)
    ncols = size(m, 2)
    for i in axes(m, 1)
        maxi = maximum(m[i, j] for j in 1:ncols)
        for j in 1:ncols
            m[i, j] /= maxi
        end
    end
    m
end

```

```julia
@btime fasterbaz2!($m);
  338.469 μs (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [February 14, 2020, 4:10pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/10 "2020-02-14T16:10:33Z")

</div>

It can be written as

```julia
function baa!(m)
    for i in axes(m, 1)
        mval = -Inf
        for j in axes(m, 2)
            mval = mval < m[i, j] ? m[i, j] : mval
        end
        for j in axes(m, 2)
            m[i, j] /= mval
        end
    end
end

@btime baa!($m) # 202.932 μs (0 allocations: 0 bytes)

```

which is still slower then allocating version.

But you gave me an idea

```julia

function baa2!(m)
    maxi = Vector{Float64}(undef, size(m, 1))
    @inbounds for i in axes(m, 1)
        mval = -Inf
        for j in axes(m, 2)
            mval = mval < m[i, j] ? m[i, j] : mval
        end
        maxi[i] = mval
    end
    @inbounds for j in axes(m, 2)
        for i in axes(m, 1)
            m[i, j] /= maxi[i]
        end
    end
end

@btime baa2!($m) # 123.239 μs (1 allocation: 7.94 KiB)

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 14, 2020, 4:17pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/11 "2020-02-14T16:17:52Z")

</div>

I got one more: although it’s getting a bit ridiculous syntax wise 🙂

```julia
function fasterbaz3!(m)
    nrows, ncols = size(m)

    maximums = m[:, 1] # copying the first col saves one col in the first iteration haha

    # iterate down the rows first which matches julia's memory layout
    @inbounds for j in 2:ncols, i in 1:nrows
        maximums[i] = max(maximums[i], m[i, j])
    end

    @inbounds for j in 1:ncols, i in 1:nrows
        m[i, j] /= maximums[i]
    end
end

```

```julia
@btime fasterbaz3!($m);
  113.390 μs (1 allocation: 7.94 KiB)

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 14, 2020, 4:18pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/12 "2020-02-14T16:18:53Z")

</div>

haha nice exactly the same moment

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 14, 2020, 4:30pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/13 "2020-02-14T16:30:46Z")

</div>

ok ok very last one! let’s use the fact that multiplications are faster than divisions…

```julia
function fasterbaz4!(m)
    nrows, ncols = size(m)

    maximums = m[:, 1]

    @inbounds for j in 2:ncols, i in 1:nrows
        maximums[i] = max(maximums[i], m[i, j])
    end

    # now maximums are actually their inverse for multiplication below
    maximums .= 1 ./ maximums

    @inbounds for j in 1:ncols, i in 1:nrows
        m[i, j] *= maximums[i]
    end
end

```

```julia
@btime fasterbaz4!($m);
  79.004 μs (1 allocation: 7.94 KiB)

```

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [February 14, 2020, 4:33pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/14 "2020-02-14T16:33:39Z")

</div>

This is so so so cool!!!

And now my turn

```julia

function baa3!(m)
    maxi = m[:, 1]
    ncol = size(m, 2)
    @inbounds for j in 2:ncol
        for i in axes(m, 1)
            maxi[i] = maxi[i] < m[i, j] ? m[i, j] : maxi[i]
        end
    end

    maxi .= 1 ./ maxi
    @inbounds for j in axes(m, 2)
        for i in axes(m, 1)
            m[i, j] *= maxi[i]
        end
    end
end

@btime baa3!($m) # 34.706 μs (1 allocation: 7.94 KiB)

```

---

<div class="post-metadata">

**Author:** ![sairus7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sairus7/32/10816_2.png) [@sairus7](https://discourse.julialang.org/u/sairus7)\
**Post date:** [February 14, 2020, 10:32pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/15 "2020-02-14T22:32:31Z")

</div>

Try changing `? :` to `ifelse`

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [February 14, 2020, 11:52pm UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/16 "2020-02-14T23:52:05Z")

</div>

Wow! I’m shocked at that performance difference. There was definitely going to be a penalty for iterating on a DataFrame but… wow.

---

<div class="post-metadata">

**Author:** ![aaowens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aaowens/32/12101_2.png) [@aaowens](https://discourse.julialang.org/u/aaowens)\
**Post date:** [February 15, 2020, 12:34am UTC](https://discourse.julialang.org/t/how-would-i-divide-each-row-of-a-julia-dataframe-by-that-rows-maximum-and-return-a-new-dataframe/34597/17 "2020-02-15T00:34:46Z")

</div>

> [@tk3369](#):
>
> julia\> df = DataFrame([Symbol(“c$i”) =\> rand(1000) for i in 1:100]…); julia\> size(df) (1000, 100) julia\> @btime foo($df); 5.139 s (55639946 allocations: 1003.91 MiB) julia\> @btime bar($df); 41.489 ms (555946 allocations: 10.83 MiB)

Something is going wrong with that `maximum` broadcast.

```julia
julia> foo2(df) = df ./ [maximum(row) for row in eachrow(df)]
foo2 (generic function with 1 method)

julia> @btime foo2($df)
  29.195 ms (554947 allocations: 10.81 MiB)

```

That being said, it’s a lot better with Tables.rows instead of eachrow.

```julia
julia> foo2(df) = df ./ [maximum(row) for row in Tables.rows(df)]
foo2 (generic function with 1 method)

julia> @btime foo2($df)
  12.237 ms (9063 allocations: 985.81 KiB)

```
