Yesterday I looked at the built-in `max()` function. Today, I'll explore #NumPy's version:

`np.max()` or `np.amax()`

There are many differences between the built-in function and NumPy's version. So let's explore…

/1 import numpy as np  # Let's create some random numbers in a
Here's yesterday's thread about the built-in `max()` if you'd like to start from there:

/2
Let's start by importing NumPy and creating an array to use to explore `np.amax()`

You can read more about using `np.random.default_rng()` to create a `Generator` instance, which is NumPy's preferred way of creating random numbers, in the quoted thread

<Code in ALT text>

/3 import numpy as np  # Let's create some random numbers in a
I'm using the `seed` parameter in `default_rng()`. This ensures I get the same numbers each time I run the code which makes it easier to explore different ways of using the same function

You can remove this to get different random numbers each time you run the code

/4
You cannot use the built-in `max()` function directly on the array `numbers` because it has more than one dimension

If you try to call `max(numbers)`, you'll get a `ValueError`

The built-in `max()` will work on one-dimensional NumPy arrays

/5
So, we'll need to use NumPy's version of this function

Although you can use `np.max()`, this function is an alias for `np.amax()`, so I'll use `np.amax()` directly

This also reminds us of the differences between the built-in and NumPy versions!

/6 import numpy as np  # Let's create some random numbers in a
The largest number in the 2D array is 87

By default, `np.amax()` finds the maximum across the whole array. It flattens the array to find the maximum value

/7
However, you may be interested in finding the maximum value in each column

You can use the `axis` parameter to choose which axis to go along when looking for the maximum

/8 import numpy as np  # Let's create some random numbers in a
The array has shape `(3, 5)`. Therefore `axis=0` represents the dimension with a value of 3

The output is a 1D array of length 5 where each value is the maximum value in each column of the original array `numbers`

/9
If you want to find the maximum in each row, then you can use `axis=1`

If you can't quite remember which axis you need to get the functions to operate along rows or columns, just use trial and error. I often do this!

/10 import numpy as np  # Let's create some random numbers in a
The output is now a 1D array of length 3, the same as the number of rows in the original array

The values are the maximum in each row

/11
The result of `np.amax()` for the 2D array we're using is a 1D array when using a single axis, as in the previous two examples

You may need to keep the same number of dimensions in your output. In this case, you can use the `keepdims` parameter

/12 import numpy as np  # Let's create some random numbers in a
The output from `np.amax()` is now also a 2D array. You can see this from the number of pairs of square brackets you see in the output

You can also access the `shape` attribute which will show you that the output has shape `(3, 1)` It's a 2D array with 3 rows and 1 column

/13
The values are the same as the ones you got when you didn't set `keepdims=True` but the shape of the output array is different

This can be useful if you want to perform operations between the original array and the `np.amax()` result since they can be broadcast together

/14
If you're not familiar with broadcasting rules in NumPy, you can have a look at this thread from a while ago:

/15
Let's pause for a second to look at the docs for `np.amax()`:
numpy.org/devdocs/refere…

Here's the signature in the docs:

numpy.amax(
a,
axis=None,
out=None,
keepdims=<no value>,
initial=<no value>,
where=<no value>
)

/16
Let's look the parameters we haven't used so far

`initial` sets a minimum value for `np.amax()`. Therefore, when looking for the maximum value, the initial value is also thrown into the mix, as seen in this example

/17 import numpy as np  # Let's create some random numbers in a
The array's maximum value is `87` which is smaller than the argument you assigned to `initial`, which is `95`

Therefore, `np.amax()` returns 95 in this case

The array's maximum value is returned if it's larger than `initial`

/18 import numpy as np  # Let's create some random numbers in a
You can also select which elements in the array to consider when looking for the maximum if you don't want to consider all of them

You can use the `where` parameter for this:

/19 import numpy as np  # Let's create some random numbers in a
We've used an array with the same shape as the original array to assign to `where`. This array contains Boolean values

Only the elements in the original array which match a `True` value in the `where` array are considered when looking for the maximum

/20
The actual highest value of `87` matches a `False`, so it's not included when looking for the maximum

Therefore, `np.amax()` returns 82, which is the highest value from those which match a `True` in `where`

/21
You may have noted I've also used `initial` in this call and set it to -1

When you use the `where` mask, you need to set an `initial` value to serve as a default in case no elements are included

/22
If you leave this out, you'll get a `ValueError` asking you to use `initial`

You'll see why this is needed in one of the last examples in this thread

/23
Let's add the `axis` parameter again to see what happens:

/24 import numpy as np  # Let's create some random numbers in a
`axis=1` looks for the maximum along rows, but the elements in each row are masked by the `where` mask which is now a 1D array

Therefore, only the first, fourth, and fifth elements in each row are considered when looking for the maximum

/25
Let's use `axis=0` to see what the output looks like

/26 import numpy as np  # Let's create some random numbers in a
The maximum values in the first, fourth, and fifth columns are shown in the output

However, since the second and third elements in `where` are `False`, none of the values in these columns are used

/27
This means that these columns don't have a maximum value

This is where the default value you set with the `initial` parameter kicks in

/28
This leaves one more parameter: `out`

This parameter allows you to place the result of `np.amax()` in another pre-existing array

In this example, we first create a `(3, 1)` array of zeros called `result` and place the output of `np.amax()` in this array

/29 import numpy as np  # Let's create some random numbers in a
Note that I'm printing the array `result` and not the value returned directly by `np.amax()` in this example

`result` is a 3 x 1 array and we're using `keepdims=True` which means that the output from `np.amax()` also has shape `(3, 1)`

/30
Let's look at one final example using the `out` parameter

In this example, you create `result` as a 3 x 3 array of zeros and you want to place the output from `np.amax()` in the first column of `result`

/31 import numpy as np  # Let's create some random numbers in a
We're no longer setting `keepdims=True` so that the output is 1D

This allows us to place it in the first column of `result` using `result[:, 0]` as the `out` argument

/32
You can spend a bit more time playing with all the options in `np.amax()`, and then you can move to 3 or more dimensional-arrays too. Just for fun!

/33

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Stephen Gruppetta

Stephen Gruppetta Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @s_gruppetta_ct

Jan 6
Let's see how to use `max()` to the max
[Sorry! Couldn't resist. I won't do that again, I promise]

You probably have used the built-in `max()` function

Let's look at all the ways we could use it

<Code in ALT text in all code snippets>

1/ some_words = [     "hello",     "goodbye"
The most common use of `max()` is probably with a list (or any iterable) of numbers

2/ numbers = [4, 10, 2, 19, 3, 12]  print(max(numbers)) # OUTPU
However, you can use `max()` with iterables of other data types, too

This is because you can use the greater than `>` operator with other data types

>>> "tomorrow" > "hello"
True

3/ some_words = [     "hello",     "goodbye"
Read 21 tweets
Dec 26, 2022
This is a common gotcha in Python

It isn't a mistake or inconsistency
There's a reason behind it

And once you understand when you use data attributes (no parentheses) and when methods (with parentheses), it will all make sense

Let's look at this example from `datetime`

/1 >>> import datetime >>> today = datetime.datetime.now() >>>
You're creating an instance of the `datetime.datetime` class when you use `now()`

As most objects, this instance will have some data attributes (you may call them instance variables). These are the attributes that store data (that is the variables linked to the instance)

/2
You can see what data attributes `datetime.datetime` has in the docs:

docs.python.org/3/library/date…

/3
Read 18 tweets
Dec 25, 2022
A few days ago I posted a "countdown to Christmas" code. Here's the updated version…

This should work before, on, and after Christmas day…

See below for a brief walk through…

<code in ALT text>

/1 import datetime import math  today = datetime.datetime.now()
We start by getting today's date using datetime's `now()` function

/2
Next, we use the if...else ternary operator to select the year for Christmas Day

If it happens to be one of the few days after Christmas Day (26-31 Dec), then we use next year's year, otherwise we use this year's

/3
Read 6 tweets
Dec 24, 2022
In what situations is NumPy faster than vanilla Python?

Short answer: if you want to perform the same operation on each item in a sequence, it's likely NumPy will be faster

Let's look at an example in which we compare using lists with append, list comprehensions, and NumPy

/1 https://gist.github.com/stephengruppetta/6fd6c85144027c6cb4b
This is a classic: converting from ºCelsius to ºFahrenheit

Caveat: timing operations can be tricky and will vary from system to system and on other factors–so consider values as illustrative only

/2
In this example, there's a list of 10 million temperatures and a NumPy array version of the same values

We test three scenarios be defining three functions:

• looping through a list and using `append()` to add to a new list
• using list comprehensions
• using NumPy

/3
Read 9 tweets
Dec 23, 2022
The way Python deals with variables is different from some other languages. You may even have heard some say they're not technically variables

Let's visualise what's happening when you create a name in Python and assign data to it with The Box and Label analogy

/1 >>> numbers = [3, 10, 8, 2]...Image
Before we start, as this is a visual analogy, it doesn't perfectly represent what's happening underneath the hood in Python

But it will give you a good understanding of what "assigning data to a name" does…

/2
Let's write the following:

>>> numbers = [3, 10, 8, 2]

Picture a box such as the cardboard box shown here

The object (on the right of =) goes inside the box

In this case, the list [3, 10, 8, 2] goes inside the box

You also stick a label on the box with `numbers` on it

/3 Box with label `numbers` an...
Read 24 tweets
Dec 12, 2022
Here's a question you know the answer to:

"How does a Python `for` loop work?"

"What a silly question", I can hear you think. But, do you _really_ know what's happening behind the scenes?

Let's have a look at iterables, iterators, and the `for` loop…

/1
Ready for this?!

The next tweet is deliberately wordy, but we'll flesh it out in the rest of the thread

Hold on tight, and let's go…

/2
An iterable is a data type that can be used in a `for` loop. You can iterate through an iterable

But, when you use an iterable in a `for` loop, an iterator is created from the iterable

An iterator is a stream of data which you can only go through once

/3
Read 34 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(