198
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

【超初心者向け】Numpy基礎50本ノック

みなさん、こんにちは。
こちらは「ABEJAアドベントカレンダー2020」の15日目の記事です。

はじめに: 文系営業がDeep Learningの勉強を始めて

AIどころかエンジニア知識もない文系出身の私がABEJAにビジネス担当として飛び込んで、早数年。
やっと営業やマーケティングに困らない知見はついたものの、ABEJAにはデータサイエンス・ビジネスどちらもできるような人ばかり。少しでも追いつこうと、日本ディープラーニング協会のE資格の勉強をはじめました。

ただ、Pythonの実装経験がない中で学習し始めたため、ゼロから作るDeep Learningの最初の30ページあたりで既につまずき、その後は1ページ進むのに1時間かかるような始末。
特にNumpyの関数がわからず苦戦したので、自身の勉強メモを一覧化して、同じような挫折を味わいかけている方に共有しようと思った次第です。

対象となる読者の方

  • 機械学習やDeep Learningの勉強を始めたが、pythonコードがちんぷんかんぷんで挫折しかかっている方
  • データを行列として扱うためにはNumpyが便利なんだな・・くらいの理解の方
  • 100 numpy excercisesにまだ挑んでいない方、あるいは挫折した方

Numpyとは

  • 前提として、Numpyは多次元配列を扱うことに長けている、数値計算ライブラリです。機械学習やDeep Learningにおいては、データを行列として扱って計算する形で利用します。
  • Numpyの各関数や機能を使う際、はimport文、import numpy as npを使って宣言した上で、np.関数名で宣言します。
  • 本文のndarrayとは、"N dimentional array"の略で、同じ属性や大きさを持った要素を持つN次元配列を扱うためのクラスのことです。通常np.array関数などによって生成します。

50本ノックスタート

1. 配列をつくる

01. np.array

配列を作る

python.qiita.py
np.array([1, 2, 3])
->array([1, 2, 3])

02. np.zeros

要素がゼロの配列を作る

python.qiita.py
np.zeros(3, dtype=float)
->array([0., 0., 0.])

03. np.zeros_like

aと同じ形式の、要素がゼロの行列を作る

python.qiita.py
a = np.array([1, 2, 3])
np.zeros_like(a) 
->array([0, 0, 0])

04. np.ones

要素が1の配列を作る

python.qiita.py
np.ones(3)
->array([1., 1., 1.])

05. np.eye

単位行列を作る

python.qiita.py
np.eye(2)
->array([[1., 0.],
       [0., 1.]])

06. np.arange

規則的な配列を作る

python.qiita.py
np.arange(0,2, 0.5) # 始点、終点(アウトプットはこの値を含まない)、間隔を記載
->array([0. , 0.5, 1. , 1.5])

07. np.linspace

規則的な配列を作る

python.qiita.py
np.linspace(1, 10, 10) # 始点、終点(アウトプットはこの値を含む)、個数を記載
->array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])

2. 様々な乱数の配列をつくる

08. np.random.rand

0.0以上、1.0未満の一様分布の乱数を生成

python.qiita.py
np.random.rand(2) # 0〜1の乱数を2つ作成
->array([0.82954644, 0.76417915])# 乱数は都度生成される(ので左の限りではない)

np.random.rand(2, 2) # 0〜1の乱数で2x2の行列を生成
->array([[0.31443211, 0.59234688],
       [0.71882085, 0.66036226]]) 

ちなみに、np.random.random_sample()でも同様に0.0以上、1.0未満の一様分布の乱数を生成できます。

09. np.random.randint

範囲での任意の整数の乱数を生成

python.qiita.py
np.random.randint(1, 7) # 1~7未満の範囲で任意の整数が返される
->2

10. np.random.randn

平均0、分散1の標準正規分布に従う値を生成

python.qiita.py
np.random.randn() # 値を一つ作成
->0.413523804959048 

np.random.randn(2, 2) # 値を2×2行列で作成
->array([[-1.37996541, -1.41321606],
       [-1.22184305, -1.46967812]]) 

11. np.random.normal

正規分布の任意の平均・標準偏差を指定できる

python.qiita.py
np.random.normal(5, 1) # 平均5、標準偏差1の正規分布
->5.255820663352234

12. np.random.choice()

ランダムに要素を抽出

python.qiita.py
a = np.array(10)
np.random.choice(a) # 配列aの中からランダムに要素を抽出 
->9

3. 配列の参照をする

13. ndarray.ndim

行列の次元数を参照

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
a.ndim
->2

14. ndarray.size

行列の要素数を参照

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
a.size
->6

15. ndarray.shape

行・列数を参照

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
a.shape
->(2, 3)

16. ndarray.dtype

要素の型を参照

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
a.dtype
->dtype('int64')

17. [p, q]

配列のp行q列目の要素の参照

python.qiita.py
a = np.array([1, 2, 3])
a[1] # 先頭を0番目とした際の1番目の値を参照
->2

a[0:2] # 0番目から、2番目の一つ手前までを参照
->array([1, 2])


b = np.array([[1, 2 ,3],[4, 5, 6]])
b[0,1] # 0行1列目を参照
->2

b[:,1] # 1列目を参照
->array([2, 5])

b[:,[1,2]] # 1,2列目を参照
->array([[2, 3],
       [5, 6]])

なお、コロンを用いてリストや文字列の一部を参照したり取り出すことができることをスライスと呼びます。

4. 配列を操作する

18. ndarray.reshape(p, q)

p行q列の配列に変換

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
a.reshape(3, 2)
->array([[1, 2],
       [3, 4],
       [5, 6]])

19. ndarray.resize(p, q)

p行q列の配列に変換し、変更された配列がもとの配列より大きければ、必要なだけ0で埋める

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
a.resize(3, 3)
print(a)
->[[1 2 3]
 [4 5 6]
 [0 0 0]]

20. ndarray.ravel

多次元配列を1次元の行列にする

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
a.ravel()
->array([1, 2, 3, 4, 5, 6])

なお、ndarray.flattenでも同じ事ができますが、ravelの方がより高速に処理できることがあるそう。

21. np.flip

配列の要素を反対にする

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
np.flip(a)
->array([[6, 5, 4],
       [3, 2, 1]])

a[::-1,::-1]といったスライスでも同様のことができます。

22. ndarray.transpose

配列を転置する

python.qiita.py
a = np.array([[1, 2 ,3],[4, 5, 6]])
a.transpose()
->array([[1, 4],
       [2, 5],
       [3, 6]])

23. np.append

配列に要素を追加

python.qiita.py
a = np.array([1, 2, 3])
np.append(a, 4) # 末尾に4を追加
->array([1, 2, 3, 4])

np.append(0, a) # 先頭に0を追加
->array([0, 1, 2, 3])

24. np.where

条件を満たす要素を返す、あるいはTrue・Falseを判定する

python.qiita.py
a = np.arange(6).reshape((2, 3))
np.where(a < 3, True, False) # a<3の場合True、そうでない場合Falseを返す
->array([[ True,  True,  True],
       [False, False, False]])

np.where(a < 3) # a<3を満たす要素の範囲を抽出
->(array([0, 0, 0]), array([0, 1, 2]))

25. np.all

配列の要素が全て条件を満たすか否かを判定する

python.qiita.py
a = np.arange(6).reshape((2, 3))
np.all(a < 3)
->False

np.all(a < 6)
->True

26. np.any

配列の要素のいずれかが条件を満たすか否かを判定する

python.qiita.py
a = np.arange(6).reshape((2, 3))
np.any(a < 3)
->True

np.any(a > 6)
->False

27. ndarray.argmax

多次元配列の中の最大値の要素を持つインデックスを返す

python.qiita.py
a = np.array([1, 2, 3])
a.argmax()
->2

28. np.sort

配列を小さい順に並べ替える

python.qiita.py
a = np.array([8, 2, 1, 5, 6])
np.sort(a)
->array([1, 2, 5, 6, 8])

29. np.argsort

配列を小さい順に並べ替えた際の配列のインデックスを出力

python.qiita.py
a = np.array([8, 2, 1, 5, 6])
np.argsort(a)
->array([2, 1, 3, 4, 0])

30. np.expand_dims

配列に次元を追加

python.qiita.py
a = np.arange(6).reshape(2, 3)

np.expand_dims(a, 0)
->array([[[0, 1, 2],
        [3, 4, 5]]])

np.expand_dims(a, 0).shape 
->(1, 2, 3)

np.expand_dims(a, 1)
->array([[[0, 1, 2]],

       [[3, 4, 5]]])

np.expand_dims(a, 1).shape
->(2, 1, 3)

31. np.broadcast_to

ブロードキャストと呼ばれる、異なる形状の配列を自動統一を実施
特にbroadcast_toは配列を任意の形状にブロードキャストする際に使用する

python.qiita.py
a = np.arange(2)
np.broadcast_to(a,(2, 2))
->array([[0, 1],
       [0, 1]])

32. np.broadcast_arrays

複数の配列をブロードキャストして形状を揃えたい際に使用する

python.qiita.py
a = np.arange(3)
b = np.arange(3).reshape(3, 1)
np.broadcast_arrays(a, b)
->[array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]]), array([[0, 0, 0],
       [1, 1, 1],
       [2, 2, 2]])]

5. 配列の演算

33. 一般的な四則演算

python.qiita.py
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

a + b
->array([5, 7, 9])

a - b
->array([-3, -3, -3])

a * b 
->array([ 4, 10, 18])

a / b
->array([0.25, 0.4 , 0.5 ])

a **2 # aの2乗
->array([1, 4, 9])

34. np.add(a, b)

a, bの足し算

python.qiita.py
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

np.add(a,b)
->array([5, 7, 9])

35. np.subtract(a, b)

a, bの引き算

python.qiita.py
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

np.subtract(a, b)
->array([-3, -3, -3])

36. np.sum

配列の要素の合計値

python.qiita.py
a = np.array([[1, 2, 3],[4,5,6]])

np.sum(a)
->21

np.sum(a, axis=0) #列ごとの合計値
->array([5, 7, 9])

np.sum(a, axis=1) #列ごとの合計値
->array([ 6, 15])

37. np.multiply(a, b)

a, bの要素ごとの積(アダマール積)

python.qiita.py
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

np.multiply(a,b)
->array([ 4, 10, 18])

38. np.dot(a, b)

a, bの配列同士の積

python.qiita.py
a = np.arange(3).reshape(1, 3)
b = np.arange(3).reshape(3, 1)

np.dot(a,b)
->array([[5]])

※なお、引数が両方とも一次元配列の場合は内積を返します。

39. np.mean

平均の算出

python.qiita.py
a = np.arange(10).reshape(2, 5)
np.mean(a)
->4.5

40. np.std

標準偏差の算出

python.qiita.py
a = np.arange(10).reshape(2, 5)
np.std(a)
->2.8722813232690143

41. np.power

累乗の計算

python.qiita.py
np.power(2,3) #2の3乗
->8

a = np.array([1, 2, 3])
np.power(a, 2)
->array([1, 4, 9])

42. np.sqrt

平方根の計算

python.qiita.py
np.sqrt(4) 
->2.0

a = np.array([1, 4, 9])
np.sqrt(a) 
->array([1., 2., 3.])

43. np.max

最大値を返す

python.qiita.py
a = np.array([1, 2, 3])
np.max(a) 
->3

44. np.min

最小値を返す

python.qiita.py
a = np.array([1, 2, 3])
np.min(a) 
->1

45. np.abs

絶対値を求める

python.qiita.py
np.abs(-1)
->1

46. np.exp(x)

eのx乗

python.qiita.py
np.exp(1)
->2.718281828459045

47. np.log(x)

eを底とするxの対数

python.qiita.py
np.log(1)
->0.0

48. np.sin

sinを求める

python.qiita.py
np.sin(1)
->0.8414709848078965

49. np.cos

python.qiita.py
np.cos(1)
->0.5403023058681398

50. np.tan

python.qiita.py
np.tan(1)
->1.557407724654902

さいごに

いかがでしたでしょうか。Pythonや機械学習の初学者の方の参考に少しでもなれば幸いです。
また、この記事は初心者が書いていますので、違う点やアドバイスなどあればお気軽に教えていただけたら嬉しいです。
(もっと機械学習に使うものがあれば、追記か入れ替えをしようかと思っています)

ちなみに、この記事を書く際にも、ABEJAのデータサイエンティストや、データサイエンス知見のあるプロジェクトマネジャーの皆さんにアドバイスをもらいました(皆さんありがとう・・・)。
ABEJAには技術・事業双方に知見を持つメンバーがたくさんいます。少しでもご興味のある方、採用募集しておりますのでぜひお声がけください!

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
Sign upLogin
198
Help us understand the problem. What are the problem?