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

【Python】二次元配列を自在に操れ。【初期化・参照・抽出・計算・転置】

はじめに

Pythonを学ぶ上で避けては通れない二次元配列の操作(初期化・参照・抽出・計算・転置)をまとめました。
(※numpyモジュールのインストールが必要。macの場合は、terminalからpip3 install numpyでインストール可能。windowsの場合は、こちらを参考に、、WindowsでPython3, numpy, pandas, matplotlibなどインストール)
基本的に以下のようなコードでコードと出力結果を記載します。

ex.py
code = 'コード'
# 出力結果

リストの初期化

例として、2行3列[[0, 0, 0], [0, 0, 0]]の2次元配列を次の2通りの方法で作成する。

1. リスト内包表記を使って二次元配列を作る

ex1.py
a = [[0 for j in range(3)] for i in range(2)]
print(a)
# [[0, 0, 0], [0, 0, 0]]

a[0][0] = 1
print(a)
# [[1, 0, 0], [0, 0, 0]]

2. numpyモジュールを使って二次元配列を作る

ex2.py
import numpy as np

a = np.zeros((2, 3))
print(a)
# [[0, 0, 0],
#  [0, 0, 0]]

print(a)
a[0][0] = 1
# [[1, 0, 0], 
#  [0, 0, 0]]

一次元の配列を二次元に変換

例:0~5までの数字を2行3列の二次元配列に代入する場合
(※-1を使うとその次元のサイズは他の次元から自動的に算出される。)

ex.py
import numpy as np

#0~5までの配列を自動生成
a = np.arange(6)
print(a)
# [0 1 2 3 4 5]

#一次元配列aを二次元配列に変換
print(a.reshape(2, 3))
# [[0 1 2]
#  [3 4 5]]

print(a.reshape(-1, 3))
# [[0 1 2]
#  [3 4 5]]

print(a.reshape(2, -1))
# [[0 1 2]
#  [3 4 5]]

範囲を指定してアクセスする

範囲を指定してアクセスする場合は、X[start:end:step]のように指定する。
このときendは含まれないので注意が必要。(Matlabではendは含まれる。)
startを省略すると最初からになり、endを省略すると最後までになり、stepを省略するとstepが1になる。

多次元の場合は、カンマ(,)で区切ってそれぞれを指定する。指定の仕方は一次元の時と同じ。

ex.py
import numpy as np

a = np.arange(12).reshape(3, 4)
print(a)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

#a[行の範囲, 列の範囲]
print(a[:3, 1:3])
# [[1 2]
#  [5 6]
#  [9, 10]

print(a[:, 1])
# [[1] 
#  [5]
#  [9]]

条件を満たすデータを取り出す

ex.py
import numpy as np

a = np.arange(12).reshape(3, 4)
print(a)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

#条件を満たす箇所がTrue,満たさない箇所がFalseとなるnumpy arrayが返される。
print(a > 5)
# [[False False False False]
#  [False False  True  True]
#  [ True  True  True  True]]

#条件を満たす箇所の値が返される。
print( a[a > 5] )
# [ 6  7  8  9 10 11]

各列・各行の最大値を求める

第二引数axisを指定すると、各軸に沿って最大値となるインデックスが返される。
例えばaxis=0とすると各列ごとの最大値の行番号が返される。各列の最大値そのものはnp.max()axis=0とすると得られる。(axis=1とすると行ごとの最大値の列番号が返される。)

ex.py
import numpy as np

a = np.array([[20, 50, 30], [60, 40, 10]])
print(a)
# [[20 50 30]
#  [60 40 10]]

#axis=1とすると列ごとの最大値の列番号が返される。
print(np.argmax(a, axis=0))
# [1 0 0]

#列ごとの最大値
print(np.max(a, axis=0))
# [60 50 30]


#同様にaxis=1とすると行ごとの最大値の列番号が返される。
print(np.argmax(a, axis=1))
# [1 0]

#行ごとの最大値
print(np.max(a, axis=1))
# [50 60]

同様に以下の応用が可能である。
numpy.sum(): 合計
numpy.mean(): 平均
numpy.min(): 最小 / numpy.max(): 最大
・そのほか(numpy.std(): 標準偏差 / numpy.var(): 分散など)

二次元配列(行列)の転置

T属性(.T)

T属性で元の二次元配列(行列)の転置行列を取得できる。

ex1.py
import numpy as np

import numpy as np

a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
#  [3 4 5]]

a_T = a.T
print(a_T)
# [[0 3]
#  [1 4]
#  [2 5]]

・T属性が返すのは元の配列のビュー(参照)であり、いずれかの要素を変更するともう一方の要素も変更される。
・2つのndarrayが同じメモリのデータを参照している(片方がもう片方のビューである)かどうかはnp.shares_memory()で確認できる。

ex2.py
print(np.shares_memory(a, a_T))
# True

a_T[0, 1] = 100
print(a_T)
# [[  0 100]
#  [  1   4]
#  [  2   5]]

print(a)
# [[  0   1   2]
#  [100   4   5]]

別々のデータとして処理したい場合はcopy()でコピーを作成する。

ex3.py
a_T_copy = a.T.copy()
print(a_T_copy)
# [[0 3]
#  [1 4]
#  [2 5]]

print(np.shares_memory(a, a_T_copy))
# False

a_T_copy[0, 1] = 100
print(a_T_copy)
# [[  0 100]
#  [  1   4]
#  [  2   5]]

print(a)
# [[0 1 2]
#  [3 4 5]]

最後に

他にも良い解法や知っておくと便利な情報があれば教えてもらえると嬉しいです。

sho11hei12-1998
石川住みの大学生です。 独学でフロントエンドの勉強を始め、現在はホームページを作成し、運営しています。 大学では、バックエンドの勉強をしています。 instagram ▶︎ @__shohei.12
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
ユーザーは見つかりませんでした