python Numpyメモ

##Numpyについての復習
教材：
https://www.udemy.com/the-python-mega-course/learn/v4/content

##Numpy
numpyはpandasのベースとなっているライブラリー。他にも様々なライブラリーのベースになっている。主にn次元のarrayを扱うライブラリー。list型とは少し違う。

```py
import numpy

n=numpy.arange(27)
type(n)
>>>numpy.ndarray

print(n)
>>>array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8],
       [ 9, 10, 11, 12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23, 24, 25, 26]])


#2次元
n.reshape(3,9)
>>>array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8],
       [ 9, 10, 11, 12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23, 24, 25, 26]])
n.reshape(2,9)
>>>ValueError: cannot reshape array of size 27 into shape (2,9)

#3次元
n.reshape(3,3,3)
>>>array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])
```
1. `numpy.arange([start,] stop[, step,], dtype=None)`。指定したstepsizeのstopの数値を含まない一次元のarrayを作成してくれる。start,stop,step,endはnumberを受け取る。startのデフォルトは0。
2. データ型の`ndarray`のndはn dimension。n次元のarray。
3. 上記のnを出力すると、[row1,column27]のarrayとして出力される。
4. `numpy.ndarray`オブジェクトに対して、`reshape()`メソッドで2次元のarrayにすることができる。。2次元に再形成するなら`reshape(arg1,arg2)`において、arg1*arg2が元の1次元arrayの長さに等しい必要がある。nの長さは27。3*9=27。さもなければエラー。
5. 3次元でも同上。3*3*3=27。


```py
m = numpy.asarray([[123,12,123,12,1],[],[]])
print(m)
>>>[list([123, 12, 123, 12, 1]) list([]) list([])]
print(type(m))
>>><class 'numpy.ndarray'>
```
1. pythonのlist型を引数にとって、`arassay()`メソッドで`numpy.ndarray`オブジェクトを作ることもできる。これは二次元のarray


##画像を読み込んでndarrayにする
OpenCVライブラリーを使って画像を読み込むことができる。読み込んだ画像はカラーならBGR(Blue, Green, Redの順番)で読み込まれる。
コンピューターは簡単に数字を色に変換できる。
使う画像：
[smallgray.png](https://qiita-image-store.s3.amazonaws.com/0/234410/1055f657-48f6-fc4d-3f56-dc293796c325.png)
超極小

```py

import cv2

#image read as gray scale
img=cv2.imread("smallgray.png", 0)
print(img)
>>>[[187 158 104 121 143]
 [198 125 255 255 147]
 [209 134 255  97 182]]

#image read as BGR color
img = cv2.imread("smallgray.png", 1)
ptin(img)
>>>array([[[187, 187, 187],#row1,column1:[blue,green,red]
        [158, 158, 158],#row1,column2:[blue,green,red]
        [104, 104, 104],#row1,column3:[blue,green,red]
        [121, 121, 121],
        [143, 143, 143]],

       [[198, 198, 198],#row2,column1:[blue,green,red]
        [125, 125, 125],
        [255, 255, 255],
        [255, 255, 255],
        [147, 147, 147]],

       [[209, 209, 209],
        [134, 134, 134],#row2,column2:[blue,green,red]
        [255, 255, 255],
        [ 97,  97,  97],
        [182, 182, 182]]], dtype=uint8)

#image write
cv2.imwrite("newsmallgray.png", img)

```
1. 3*5pixelの画像を`cv2.imread(filepath[, ])`メソッドで読み込んだ。filepath以降の数字は0ならgrayscale(灰色ベース)で読み込む。grayscaleは0黒-255白の範囲で灰色を示す。グレイスケールは2次元である。今回の場合rowが3つ、rowの中にcolumn5つのarrayができる。
2. `cv2.imread(filepath, 1)`で読み込むとBGRベースで読み込まれる。3次元のarrayができる。[187,187,187]は[blue, green, red]をそれぞれ表す。数値の範囲は0-255である。

###スライス
```py
import cv2
img=cv2.imread("smallgray.png", 0)
print(type(img[:1,2:5]))
>>><class numpy.ndarray>

print(img[:1,2:5])
>>>[[104 121 143]]

#all row
print(img[:,1:3])
>>>[[158 104]
 [125 255]
 [134 255]]

#a element
print(img[2,1])
>>>134

#python list
l = [[1,2,3,4],[4,5,6,7]]
l[:1,2:3]
>>>TypeError: list indices must be integers or slices, not tuple
```
1. `numpy.ndarray`オブジェクトはarray[row_range[start:end], column_range[start:end]]の形式でスライスができる。start位置から始まり、endの要素は含まれない
2. 座標を指定することもできる。
3. pythonのlistでは同じような方法でスライスしようとすると、TypeErrorになる。

###iterate
```py
for i in img:
    print(i)
>>>[187 158 104 121 143]
[198 125 255 255 147]
[209 134 255  97 182]

#transpose
for i in img.T:
    print(i)
>>>[187 198 209]
[158 125 134]
[104 255 255]
[121 255  97]
[143 147 182]
img_t=img.T
cv2.imwrite("transpoted_grayscale.png")

#flat
print(img.flat)
>>><numpy.flatiter object at 0x7fc04c307c00>
for i in img.flat:
    print(i)
>>>187
158
104
121
143
198
125
255
255
147
209
134
255
97
182
```

1. `numpy.ndarray`をiterateすることもできる。rowごとにloop処理がされる。
2. `.T`はrowとcolumnの`numpy.ndarray`の位置関係を置き換える。transpose。row3つ、column5つならば。column5つ、row3つのarrayになるように位置関係を逆転させる。言葉だとわかりにくいけど、実際に画像を`imwrite`で作ってみると一目瞭然。といいつつ、グレイスケールだからぶっちゃけわかりにくし。
3. `img.flat`はgeneratorみたいな感じ？n次元だろうと、1次元の配列にならしてくれる。つまり要素は1つずつ取り出される。


###結合：concatenation
```py
#horizontal : 水平の
img_hs=numpy.hstack((img,img,img))
print(img_hs)
>>>array([[187, 158, 104, 121, 143, 187, 158, 104, 121, 143, 187, 158, 104,
        121, 143],
       [198, 125, 255, 255, 147, 198, 125, 255, 255, 147, 198, 125, 255,
        255, 147],
       [209, 134, 255,  97, 182, 209, 134, 255,  97, 182, 209, 134, 255,
         97, 182]], dtype=uint8)
cv2.imwrite("hstest.png", img_hs)

#vertical :　垂直の
im_a = [1,2,3]
img_vs=numpy.vstack((img,img_a))
img_vs
>>>ValueError: all the input array dimensions except for the concatenation axis must match exactly

```
1. `hstack`で2つ以上の`numpy.ndarray`オブジェクトを水平方向にくっつける。columnが増えるってこと。2次元の配列なら2次元の配列としかくっつけることができない。次元数を揃える必要があるってこと
2. `vstack`で垂直方向にくっつける。rowが増えるってこと。2次元なら2次元の配列と(ry。ValuerErrorになる。


###切断：split
```py
img_hs
>>>>>>array([[187, 158, 104, 121, 143, 187, 158, 104, 121, 143, 187, 158, 104,
        121, 143],
       [198, 125, 255, 255, 147, 198, 125, 255, 255, 147, 198, 125, 255,
        255, 147],
       [209, 134, 255,  97, 182, 209, 134, 255,  97, 182, 209, 134, 255,
         97, 182]], dtype=uint8)

#horizontal split
lst = numpy.hsplit(img_hs, 5)
lst
>>>>>>[array([[187, 158, 104],
        [198, 125, 255],
        [209, 134, 255]], dtype=uint8), 
array([[121, 143, 187],
        [255, 147, 198],
        [ 97, 182, 209]], dtype=uint8), 
array([[158, 104, 121],
        [125, 255, 255],
        [134, 255,  97]], dtype=uint8), 
array([[143, 187, 158],
        [147, 198, 125],
        [182, 209, 134]], dtype=uint8), 
array([[104, 121, 143],
        [255, 255, 147],
        [255,  97, 182]], dtype=uint8)]

#vertical split
lst = numpy.vsplit(img_hs, 3)
lst
>>>[array([[187, 158, 104, 121, 143, 187, 158, 104, 121, 143, 187, 158, 104,
         121, 143]], dtype=uint8),
 array([[198, 125, 255, 255, 147, 198, 125, 255, 255, 147, 198, 125, 255,
         255, 147]], dtype=uint8),
 array([[209, 134, 255,  97, 182, 209, 134, 255,  97, 182, 209, 134, 255,
          97, 182]], dtype=uint8)]
lst = numpy.vsplit(img_hs, 2)
>>>ValueError: array split does not result in an equal division
```
1. `hsplit(numpy.ndarray object, rowの中のcolumnの約数)`で`numpy.ndarray`をぶった切れる。columnの数15ゆえに、1,3,5を指定できる。それ以外の数値を渡すとValueError: array split does not result in an equal divisionがでる。
2. `hsplit`はrow数の約数で切る。今回はrow3つなので、1,3のみ。


##あとがき
以上メモ。jupyterlabのshift+tabでヘルプを見れるが、helpのhelpがいる。