In [1]:
# Text for Data_Analisys with Python
import numpy as np

# 1次元配列

li = [1,2,3,4,5]   # [1,2,3,4,5]
arr = np.array(li) # array([1, 2, 3, 4, 5]

type(arr)            # numpy.ndarray
arr.shape          #(5,)
Out[1]:
(5,)
In [2]:
#2次元配列

li = [[1,2,3,4],[5,6,7,8]] # [[1, 2, 3, 4], [5, 6, 7, 8]]
arr = np.array(li)
    #array([[1, 2, 3, 4],
    #       [5, 6, 7, 8]])
    
arr.shape  # (2, 4) 2行4列
Out[2]:
(2, 4)
In [3]:
# 変形 reshape

li = [1,2,3,4,5,6]
arr = np.array(li)

arr = arr.reshape(2,3) # 2行3列に変形
    #array([[1, 2, 3],
    #       [4, 5, 6]])
    
arr = arr.ravel() # "浅いコピー"で1次元配列にする
    # array([1, 2, 3, 4, 5, 6])
    
arr = arr.reshape(2,3) # 再び2行3列に変形
    #array([[1, 2, 3],
    #       [4, 5, 6]])
    
arr = arr.flatten() # "浅いコピー"で1次元配列にする
    # array([1, 2, 3, 4, 5, 6])

"""補足
np.reshape(引数)はタプルで与えても同じ。
arr.reshape((2,3))
"""
Out[3]:
'補足\nnp.reshape(引数)はタプルで与えても同じ。\narr.reshape((2,3))\n'
In [4]:
li = [1,2,3,4,5,6]

# リストのスライスは深いコピー
li_deep = li[:]

# リストの代入は浅いコピー
li_shallow =li

#確認
li_deep[3]=100
li_deep     # [1, 2, 3, 100, 5, 6]

li         #[1, 2, 3, 4, 5, 6] 

li_shallow[4] = 200
li_shallow # [1, 2, 3, 4, 200, 6]
li         # [1, 2, 3, 4, 200, 6] #元リストにも影響あり

"""深いコピーをするときは
スライスをするとよい。li2 = li[:]

正統な方法としては、li2=li.copy()
がある。
"""
Out[4]:
'深いコピーをするときは\nスライスをするとよい。li2 = li[:]\n\n正統な方法としては、li2=li.copy()\nがある。\n'
In [5]:
li = [1,2,3,4,5,6]
arr = np.array(li)

# np.array() のスライスは浅いコピー
arr_shallow = arr[:]
arr_shallow # array([1, 2, 3, 4, 5, 6])

# 確認
arr_shallow[3] = 300
arr_shallow # array([  1,   2,   3, 300,   5,   6])
arr         # array([  1,   2,   3, 300,   5,   6])

"""深いコピーするときは
li.copy()と同様に
arr.copy()をすればよい。
"""

li = [1,2,3,4,5,6]
arr = np.array(li)
arr_deep = arr.copy()
arr_deep[1] = 500
arr_deep # array([  1, 500,   3,   4,   5,   6])
arr      #array([1, 2, 3, 4, 5, 6])

"""
リストと np.arrayの共通項を考慮すれば
深いコピーをするときは
li.copy()   arr.copy()
を使用すれば良い。
"""
Out[5]:
'\nリストと\u3000np.arrayの共通項を考慮すれば\n深いコピーをするときは\nli.copy()   arr.copy()\nを使用すれば良い。\n'
In [6]:
# 数列を作成
np.arange(10)
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

np.arange(3,10,2)
# array([3, 5, 7, 9])

np.arange
Out[6]:
<function numpy.core.multiarray.arange>
In [7]:
# ====    乱数生成    ====

# 乱数 0 to 1 一様分布
np.random.seed(0)       #乱数シードの固定 シード番号0と定義
arr = np.random.random((3,2)) #3行2列 タプルで入れる
# array([[0.5488135 , 0.71518937],
#        [0.60276338, 0.54488318],
#        [0.4236548 , 0.64589411]])
In [8]:
# 乱数 0 to 1 一様分布
np.random.seed(1)
np.random.rand(3,2) # random.randomと違ってタプルにしなくていい。
# array([[4.17022005e-01, 7.20324493e-01],
#        [1.14374817e-04, 3.02332573e-01],
#        [1.46755891e-01, 9.23385948e-02]])
Out[8]:
array([[4.17022005e-01, 7.20324493e-01],
       [1.14374817e-04, 3.02332573e-01],
       [1.46755891e-01, 9.23385948e-02]])
In [9]:
# 乱数 整数の一様分布
np.random.seed(2)
np.random.randint(10) # 8
np.random.randint(0,10,(3,5))
# array([[8, 6, 2, 8, 7],
#        [2, 1, 5, 4, 4],
#        [5, 7, 3, 6, 4]])
Out[9]:
array([[8, 6, 2, 8, 7],
       [2, 1, 5, 4, 4],
       [5, 7, 3, 6, 4]])
In [10]:
# 乱数  0.0以上 5,0未満の一様分布
np.random.seed(3)
np.random.uniform(0.0, 5.0, size=(2,3))

# array([[2.75398951, 3.54073911, 1.45452369],
#        [2.55413803, 4.46473477, 4.48146544]])
Out[10]:
array([[2.75398951, 3.54073911, 1.45452369],
       [2.55413803, 4.46473477, 4.48146544]])
In [11]:
# 乱数 0-1 正規分布
np.random.seed(4)
np.random.randn(2,3)
# array([[ 0.05056171,  0.49995133, -0.99590893],
#        [ 0.69359851, -0.41830152, -1.58457724]])
Out[11]:
array([[ 0.05056171,  0.49995133, -0.99590893],
       [ 0.69359851, -0.41830152, -1.58457724]])
In [12]:
# ====    特殊行列生成   ====

# ゼロ行列
np.zeros((2,3)) #タプル
# array([[0., 0., 0.],
#        [0., 0., 0.]])

# 単位行列
np.eye(2)
# array([[1., 0.],
#        [0., 1.]])

#1の行列
np.ones((2,3)) #タプル
# array([[1., 1., 1.],
#        [1., 1., 1.]])

# 任意の数の行列
np.full((2,3),2.71)
# array([[2.71, 2.71, 2.71],
#        [2.71, 2.71, 2.71]])

# np.nanの行列
np.array([1,2,np.nan,4]) 
# array([ 1.,  2., nan,  4.])

type(np.nan) # as float

"""
np.nanは floatとして扱われる。
numpyでは同じタイプでないと計算できない。
欠損値を扱うための措置
"""
print(np.nan * 100) # nan
nan
In [13]:
# ====    均等割り 0 - 5を 6等分    ====
np.linspace(0,5,6) #array([0., 1., 2., 3., 4., 5.])
Out[13]:
array([0., 1., 2., 3., 4., 5.])
In [14]:
# ====    等差数列    ====
arr1 = np.array([1,1,2,3,4,4,6])
arr2 = np.diff(arr1) # array([0, 1, 1, 1, 0, 2])
In [16]:
# ====    連結    ====
arr3 = [1,2,3]
arr4 = [10,20,30]
arr_cat = np.concatenate([arr3,arr4])
 # array([ 1,  2,  3, 10, 20, 30])

# 連結 縦ベクトル(2次元配列)
arr = np.array([[1], [2], [3]])
# array([[1],
#        [2],
#        [3]])

arr1 = np.array([[4], [5] ,[6]])
# array([[4],
#        [5],
#        [6]])

arr_cat = np.concatenate([arr, arr1],axis=1) #軸を列に指定すること
# array([[1, 4],
#        [2, 5],
#        [3, 6]])

# 連結 np.hstack
arr = np.array([[1], [2], [3]])
arr1 = np.array([[4], [5] ,[6]])

arr_hstacked = np.hstack([arr,arr1])
# array([[1, 4],
#        [2, 5],
#        [3, 6]])


# 連結 np.vstack
arr = np.array([1,2,3,4,5])
arr1 = np.array([10,20,30,40,50])
arr_vstacked = np.vstack([arr,arr1])
# array([[ 1,  2,  3,  4,  5],
#        [10, 20, 30, 40, 50]])
In [17]:
# ====    分割    ====
np.random.seed(123)
arr = np.random.randn(12).reshape(3,4)

# array([[-1.0856306 ,  0.99734545,  0.2829785 , -1.50629471],
#        [-0.57860025,  1.65143654, -2.42667924, -0.42891263],
#        [ 1.26593626, -0.8667404 , -0.67888615, -0.09470897]])

# 列を分割 1つ目は3列 2つ目は残りの1列
arr_splited_1 = np.split(arr,[3],axis=1) 

arr_splited_1[0]
# array([[-1.0856306 ,  0.99734545,  0.2829785 ],
#       [-0.57860025,  1.65143654, -2.42667924],
#       [ 1.26593626, -0.8667404 , -0.67888615]])

arr_splited_1[1]
# array([[-1.50629471],
#        [-0.42891263],
#       [-0.09470897]])

# 行を分割 1つ目は2行 2つ目は残りの1行
arr_splited_0 = np.split(arr, [2],axis=0)
arr_splited_0[0]
# array([[-1.0856306 ,  0.99734545,  0.2829785 , -1.50629471],
#       [-0.57860025,  1.65143654, -2.42667924, -0.42891263]])

arr_splited_0[1]
# array([[ 1.26593626, -0.8667404 , -0.67888615, -0.09470897]])

print(arr.shape)
arr_3, arr_4 = np.hsplit(arr, [2]) # 機能しない
arr_5, arr_6 = np.vsplit(arr, [1]) # 機能しない
(3, 4)
In [18]:
#転置行列
arr = np.array([[1,2,3],[4,5,6]])
# array([[1, 2, 3],
#        [4, 5, 6]])

arr.T
# array([[1, 4],
#        [2, 5],
#        [3, 6]])
Out[18]:
array([[1, 4],
       [2, 5],
       [3, 6]])
In [19]:
# 次元の追加
arr = np.array([1,2,3,4])
arr  # array([1, 2, 3, 4])

arr_1 = arr[np.newaxis,:] # array([[1, 2, 3, 4]])

arr_2 = arr[:,np.newaxis]
# array([[1],
#        [2],
#        [3],
#        [4]])
In [27]:
# メッシュグリッドデータの生成
arr_x = np.array([1,2,3,4,5])
arr_y = np.array([10,20,30])
xx, yy =np.meshgrid(arr_x, arr_y)

xx
# array([[1, 2, 3, 4, 5],
#        [1, 2, 3, 4, 5],
#        [1, 2, 3, 4, 5]])

yy
# array([[10, 10, 10, 10, 10],
#       [20, 20, 20, 20, 20],
#       [30, 30, 30, 30, 30]])
Out[27]:
array([[10, 10, 10, 10, 10],
       [20, 20, 20, 20, 20],
       [30, 30, 30, 30, 30]])
In [149]:
# ユニバーサルファンクション(一括変換)

# 各成分を全て絶対値にする
arr = [5, -12, -3 , 2]
np.abs(arr) # array([ 5, 12,  3,  2])

# sin cos tan
arr = np.linspace(0, 2*np.pi, 100)
np.sin(arr)
Out[149]:
array([ 0.00000000e+00,  6.34239197e-02,  1.26592454e-01,  1.89251244e-01,
        2.51147987e-01,  3.12033446e-01,  3.71662456e-01,  4.29794912e-01,
        4.86196736e-01,  5.40640817e-01,  5.92907929e-01,  6.42787610e-01,
        6.90079011e-01,  7.34591709e-01,  7.76146464e-01,  8.14575952e-01,
        8.49725430e-01,  8.81453363e-01,  9.09631995e-01,  9.34147860e-01,
        9.54902241e-01,  9.71811568e-01,  9.84807753e-01,  9.93838464e-01,
        9.98867339e-01,  9.99874128e-01,  9.96854776e-01,  9.89821442e-01,
        9.78802446e-01,  9.63842159e-01,  9.45000819e-01,  9.22354294e-01,
        8.95993774e-01,  8.66025404e-01,  8.32569855e-01,  7.95761841e-01,
        7.55749574e-01,  7.12694171e-01,  6.66769001e-01,  6.18158986e-01,
        5.67059864e-01,  5.13677392e-01,  4.58226522e-01,  4.00930535e-01,
        3.42020143e-01,  2.81732557e-01,  2.20310533e-01,  1.58001396e-01,
        9.50560433e-02,  3.17279335e-02, -3.17279335e-02, -9.50560433e-02,
       -1.58001396e-01, -2.20310533e-01, -2.81732557e-01, -3.42020143e-01,
       -4.00930535e-01, -4.58226522e-01, -5.13677392e-01, -5.67059864e-01,
       -6.18158986e-01, -6.66769001e-01, -7.12694171e-01, -7.55749574e-01,
       -7.95761841e-01, -8.32569855e-01, -8.66025404e-01, -8.95993774e-01,
       -9.22354294e-01, -9.45000819e-01, -9.63842159e-01, -9.78802446e-01,
       -9.89821442e-01, -9.96854776e-01, -9.99874128e-01, -9.98867339e-01,
       -9.93838464e-01, -9.84807753e-01, -9.71811568e-01, -9.54902241e-01,
       -9.34147860e-01, -9.09631995e-01, -8.81453363e-01, -8.49725430e-01,
       -8.14575952e-01, -7.76146464e-01, -7.34591709e-01, -6.90079011e-01,
       -6.42787610e-01, -5.92907929e-01, -5.40640817e-01, -4.86196736e-01,
       -4.29794912e-01, -3.71662456e-01, -3.12033446e-01, -2.51147987e-01,
       -1.89251244e-01, -1.26592454e-01, -6.34239197e-02, -2.44929360e-16])
In [148]:
# 自然対数 底 = ネピア数 e
arr = np.array([0, 1, 2, 3])
np.log(arr) #[      -inf 0.         0.69314718 1.09861229]

# 常用対数 底 = 10
np.log10(arr) #array([      -inf, 0.        , 0.30103   , 0.47712125])

# exp()
np.exp(1) # 2.718281828459045
C:\Users\omoiy\Anaconda3\lib\site-packages\ipykernel_launcher.py:3: RuntimeWarning: divide by zero encountered in log
  This is separate from the ipykernel package so we can avoid doing imports until
C:\Users\omoiy\Anaconda3\lib\site-packages\ipykernel_launcher.py:6: RuntimeWarning: divide by zero encountered in log10
  
Out[148]:
2.718281828459045
In [90]:
# ブロードキャス(自動拡張計算)
arr = np.array([[1,2,3], [4,5,6]])
arr2 =np.array([10,10,10])
arr_sum = arr + arr2
# array([[11, 12, 13],   # 2行ともに和算されている
#        [14, 15, 16]])

arr = np.array([[1,2,3], [4,5,6]])
arr2 =np.array([10,10,10])
arr_sub = arr - arr2
# array([[-9, -8, -7], # 2行ともに差算されている
#       [-6, -5, -4]])

arr = np.array([[1,2,3], [4,5,6]])
arr2 =np.array([10,100,1000])
arr_multi = arr * arr2
# array([[  10,  200, 3000],  # 2行ともに乗算されている
#        [  40,  500, 6000]])


arr = np.array([1,2,3])
arr2 = np.array([[1], [2], [3]])
arr + arr2
# array([[2, 3, 4], # 3x3行列に和算される
#       [3, 4, 5],
#       [4, 5, 6]])

# 自分の平均からの距離をそれぞれ求める
arr = np.array([[1,2,3], [4,5,6]])
arr2 = arr - np.mean(arr)
# array([[-2.5, -1.5, -0.5],
#        [ 0.5,  1.5,  2.5]])

# スカラーを乗ずる
arr = np.array([[1,2,3], [4,5,6]])
arr2 = arr * 10
# array([[10, 20, 30],
#        [40, 50, 60]])

# 3乗する
arr = np.array([[1,2,3], [4,5,6]])
arr2 = arr ** 3 
# array([[  1,   8,  27],
#        [ 64, 125, 216]], dtype=int32)

# ゼロを含んだ行列で除算をするときのテクニック
arr = np.array([[1,2,3], [4,5,6]])
arr2 =np.array([0,10,100])
arr_div = arr / (arr2 + 1e-6)
# array([[1.00000000e+06, 1.99999980e-01, 2.99999997e-02],
#        [4.00000000e+06, 4.99999950e-01, 5.99999994e-02]])
In [104]:
# ドット積
arr = np.array([[1,2,3], [4,5,6]])
arr2 = np.array([[10], [20], [30]])
np.dot(arr, arr2)
# array([[140],
#        [320]])

"""
arr @ arr2 でも良い
"""
Out[104]:
array([[140],
       [320]])
In [145]:
# 判定 論理値
arr = np.array([[1,2,3], [4,5,6]])
arr > 3
# array([[False, False, False],
#        [ True,  True,  True]])

# ゼロでない要素数をカウントする
np.count_nonzero(arr) # 6

# 論理式と共に使えば、条件にある要素数をカウントできる
np.count_nonzero(arr > 3) # 3

# sum を使ってもできる (True=1なので)
np.sum(arr > 3) # 3

# 全要素が条件に入るか
np.all(arr > 0) # True
np.all(arr > 1) # False

# 条件に入る要素だけを取り出す
arr_true = arr[arr > 2]
arr_true # array([3, 4, 5, 6])

# 比較
arr = np.array([[1,2,3], [4,5,6]])
arr2 =np.array([1,2,3])
arr == arr2
# array([[ True,  True,  True], #ブロードキャストが有効になっている
#        [False, False, False]])

# 条件に合うものだけを抽出
arr = np.array([[1,2,3], [4,5,6]])
arr2 = np.array([1,2,3])
arr3 = np.array([1,10,100])

arr4 = arr[(arr == arr2) | (arr > 5)]
# array([1, 2, 3, 6])

# 浮動小数点誤差を無視しながら行列が同等か調べる
arr = np.array([[1,2,3], [4,5,6]])
arr2 = np.array([[1,2,3], [4,5,7]])
np.allclose(arr, arr2, atol=1) # True
# arr2 の最後のみ誤差1を含んでいるが、atolの許容誤差以内なので
# 同じ行列とみなされる
Out[145]:
True
In [147]:
# 関数 と メソド どちらでもいい
arr = np.array([1,2,3,4,5])
np.sum(arr) # 関数 15
arr.sum()   # メソド

# arrを定義した時点でarrはクラスのインスタンスに
# なっているのでメソドが使用できる
Out[147]:
15