Help us understand the problem. What is going on with this article?

Juliaの配列で最小値・最大値のインデックスを取得する

More than 1 year has passed since last update.

はじめに

調べたところいろいろやり方があったのでまとめてみました。

バージョン

v1.1.0 です。

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.1.0 (2019-01-21)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

注意

Juliaの配列のインデックスは1始まりです。

1次元配列(重複なし)

julia> a = [2, 3, 1, 9, 4, 5]
6-element Array{Int64,1}:
 2
 3
 1
 9
 4
 5

findall関数

  • 最小値
julia> findall(x->x==minimum(a), a)
1-element Array{Int64,1}:
 3

ブロードキャストを使うともっと簡潔に書けます。

julia> findall(a .== minimum(a))
1-element Array{Int64,1}:
 3

(追記) @tenfu2tea さんからコメントをいただきました!下記のような書き方もできて、しかも早いです。

julia> findall(isequal(minimum(a)),a)
1-element Array{Int64,1}:
 3
  • 最大値
julia> findall(x->x==maximum(a), a)
1-element Array{Int64,1}:
 4
julia> findall(a .== maximum(a))
1-element Array{Int64,1}:
 4

findmin関数・findmax関数

これは、(value, index) のタプルが取得できます。

  • 最小値(findmin)
julia> findmin(a)
(1, 3)
  • 最大値(findmax)
julia> findmax(a)
(9, 4)

ですので、インデックスだけなら下記のようになります。

  • 最小値(findmin)
julia> findmin(a)[2]
3
  • 最大値(findmax)
julia> findmax(a)[2]
4

argmin関数・argmax関数

もっと簡単に取得出来る関数がありました。

  • 最小値(argmin)
julia> argmin(a)
3
  • 最大値(argmax)
julia> argmax(a)
4

1次元配列(重複あり)

julia> b = [2, 3, 1, 9, 1, 4, 9, 5, 5]
9-element Array{Int64,1}:
 2
 3
 1
 9
 1
 4
 9
 5
 5

findall関数

  • 最小値
julia> findall(x->x==minimum(b), b)
2-element Array{Int64,1}:
 3
 5
julia> findall(b .== minimum(b))
2-element Array{Int64,1}:
 3
 5
  • 最大値
julia> findall(x->x==maximum(b), b)
2-element Array{Int64,1}:
 4
 7
julia> findall(b .== maximum(b))
2-element Array{Int64,1}:
 4
 7

findfirst関数

findall の最初のインデックスだけ取得する関数です。

  • 最小値
julia> findfirst(x->x==minimum(b), b)
3
julia> findfirst(b .== minimum(b))
3
  • 最大値
julia> findfirst(x->x==maximum(b), b)
4
julia> findfirst(b .== maximum(b))
4

findlast関数

findall の最後のインデックスだけ取得する関数です。

  • 最小値
julia> findlast(x->x==minimum(b), b)
5
julia> findlast(b .== minimum(b))
5
  • 最大値
julia> findlast(x->x==maximum(b), b)
7
julia> findlast(b .== maximum(b))
7

findmin関数・findmax関数

  • 最小値(findmin)
julia> findmin(b)
(1, 3)
  • 最大値(findmax)
julia> findmax(b)
(9, 4)

これはどちらも最初のインデックスのものだけ返すようです。
インデックスだけの取得方法は上記と同じく下記のようにになります。

  • 最小値(findmin)
julia> findmin(b)[2]
3
  • 最大値(findmax)
julia> findmax(b)[2]
4

argmin関数・argmax関数

  • 最小値(argmin)
julia> argmin(b)
3
  • 最大値(argmax)
julia> argmax(b)
4

こちらも最初のインデックスのものだけ返すようです。

行列

最初から重複ありで試してみます。

julia> c = [2 3 5; 1 4 9; 1 2 9]
3×3 Array{Int64,2}:
 2  3  5
 1  4  9
 1  2  9

findall関数

  • 最小値
julia> findall(x->x==minimum(c), c)
2-element Array{CartesianIndex{2},1}:
 CartesianIndex(2, 1)
 CartesianIndex(3, 1)
julia> findall(c .== minimum(c))
2-element Array{CartesianIndex{2},1}:
 CartesianIndex(2, 1)
 CartesianIndex(3, 1)
  • 最大値
julia> findall(x->x==maximum(c), c)
2-element Array{CartesianIndex{2},1}:
 CartesianIndex(2, 3)
 CartesianIndex(3, 3)
julia> findall(c .== maximum(c))
2-element Array{CartesianIndex{2},1}:
 CartesianIndex(2, 3)
 CartesianIndex(3, 3)

CartesianIndexという型が返ってきました。

https://docs.julialang.org/en/v1/base/arrays/index.html#Base.IteratorsMD.CartesianIndex

ここで行列cCartesianIndex(2, 3)インデックスを指定してみると値9が返ってきます。

julia> c[CartesianIndex(2, 3)]
9

マニュアルの先頭の説明文をGoogle翻訳してみると

多次元インデックスAを作成します。これは、多次元配列Aのインデックスに使用できます。特に、A [I]はA [i、j、k ...]と同じです。 整数とCartesianIndexインデックスを自由に混在させることができます。 たとえば、A [Ipre、i、Ipost](IpreとIpostはCartesianIndexインデックス、iはInt)は、任意の次元の配列の1つの次元に沿って動作するアルゴリズムを書くときに便利な式です。

ということです。
(まだこれを便利に利用するくらいJuliaを使いこなせていないので試した結果だけ載せておきます)

findfirst関数

  • 最小値
julia> findfirst(x->x==minimum(c), c)
CartesianIndex(2, 1)
julia> findfirst(c .== minimum(c))
CartesianIndex(2, 1)
  • 最大値
julia> findfirst(x->x==maximum(c), c)
CartesianIndex(2, 3)
julia> findfirst(c .== maximum(c))
CartesianIndex(2, 3)

findlast関数

  • 最小値
julia> findlast(x->x==minimum(c), c)
CartesianIndex(3, 1)
julia> findlast(c .== minimum(c))
CartesianIndex(3, 1)
  • 最大値
julia> findlast(x->x==maximum(c), c)
CartesianIndex(3, 3)
julia> findlast(c .== maximum(c))
CartesianIndex(3, 3)

findmin関数・findmax関数

  • 最小値(findmin)
julia> findmin(c)
(1, CartesianIndex(2, 1))
  • 最大値(findmax)
julia> findmax(c)
(9, CartesianIndex(2, 3))

argmin関数・argmax関数

  • 最小値(argmin)
julia> argmin(c)
CartesianIndex(2, 1)
  • 最大値(argmax)
julia> argmax(c)
CartesianIndex(2, 3)
yshutaro
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした