<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Numpy 介紹
Step1:  建立 ndarray
Step2:  看 ndarray 的第一件事情：  shape , dtype
Step3:  有時候，可以看圖
Step4:  有很多其他建立的方式
Step5:  這是一堆資料
* 資料有什麼資訊？
* 資料有什麼限制？
* 這些限制有什麼意義？好處？
* 以前碰過什麼類似的東西？
* 可以套用在哪些東西上面？
* 可以怎麼用（運算）?
最簡單的計算是 逐項計算
see also np.vectorize
Step6:  Q0
Step7:  Q1
Step8:  Indexing
可以用類似 list 的 indexing
Step9:  Q2
給定
python
x = np.arange(30)
a = np.arange(30)
a[1
Step10:  ndarray 也可以
Step11:  Q3
動手試試看各種情況
比方
python
b = np.random.randint(0,99, size=(10,10))
b[
Step12:  試試看下面的結果
想一下是怎麼一回事(numpy 在想什麼？)
Step13:  Q4
把 b 中的偶數都變成 -1
Step14:  用圖形來練習
Step15:  Q
將圖片縮小成一半
擷取中間一小塊
圖片上下顛倒
左右鏡射
去掉綠色
將圖片放大兩倍
貼另外一張圖到大圖中
python
from urllib.request import urlopen
url = "https
Step16:  Q
挖掉個圓圈？ (300,300)中心，半徑 100
旋轉九十度? x,y 互換？
Step17:  indexing 的其他用法
Step18:  Reshaping
.flatten 拉平看看資料在電腦中如何儲存？
查看
.reshape, .T, np.rot00, .swapaxes .rollaxis
然後再做一下上面的事情
Step19:  堆疊在一起
查看 np.vstack np.hstack np.concatenate 然後試試看
Step20:  作用在整個 array/axis 的函數
Step21:  多重意義的運用， 水平平均，整合垂直平均
Step22:  Tensor 乘法
先從點積開始
Step23:  矩陣乘法
如果忘記矩陣乘法是什麼了， 參考這裡  http
<ASSISTANT_TASK:>
Python Code:
# 起手式
import numpy as np
Explanation: Numpy 介紹
End of explanation
np.array([1,2,3,4])
x = _
y = np.array([[1.,2,3],[4,5,6]])
y
Explanation: 建立 ndarray
End of explanation
x.shape
y.shape
x.dtype
y.dtype
Explanation: 看 ndarray 的第一件事情：  shape , dtype
End of explanation
# import matplotlib
%matplotlib inline
import matplotlib.pyplot as plt
# 畫圖
plt.plot(x, 'x');
Explanation: 有時候，可以看圖
End of explanation
# 建立 0 array
np.zeros_like(y)
np.zeros((10,10))
# 跟 range 差不多
x = np.arange(0, 10, 0.1)
# 亂數
y = np.random.uniform(-1,1, size=x.shape)
plt.plot(x, y)
Explanation: 有很多其他建立的方式
End of explanation
x = np.linspace(0, 2* np.pi, 1000)
plt.plot(x, np.sin(x))
Explanation: 這是一堆資料
* 資料有什麼資訊？
* 資料有什麼限制？
* 這些限制有什麼意義？好處？
* 以前碰過什麼類似的東西？
* 可以套用在哪些東西上面？
* 可以怎麼用（運算）?
最簡單的計算是 逐項計算
see also np.vectorize
End of explanation
#可以用 %run -i 跑參考範例
%run -i q0.py
# 或者看看參考範例
#%load q0.py
Explanation: Q0:
畫出 $y=x^2+1$ 或其他函數的圖形
用
python
plt.plot?
看看 plot 還有什麼參數可以玩
End of explanation
# 參考答案
#%load q1.py 
Explanation: Q1:
試試看圖片。
使用
```python
from PIL import Image
讀入 PIL Image (這張圖是從 openclipart 來的 cc0)
img = Image.open('img/Green-Rolling-Hills-Landscape-800px.png')
圖片轉成 ndarray
img_array = np.array(img)
ndarray 轉成 PIL Image
Image.fromarray(img_array)
```
看看這個圖片的內容, dtype 和 shape
End of explanation
a = np.arange(30)
a
a[5]
a[3:7]
# 列出所有奇數項
a[1::2]
# 還可以用來設定值
a[1::2]  = -1
a
# 或是
a[1::2] = -a[::2]-1
a
Explanation: Indexing
可以用類似 list 的 indexing
End of explanation
%run -i q2.py
#%load q2.py
Explanation: Q2
給定
python
x = np.arange(30)
a = np.arange(30)
a[1::2] = -a[1::2]
畫出下面的圖
End of explanation
b = np.array([[1,2,3], [4,5,6], [7,8,9]])
b
b[1][2]
b[1,2]
b[1]
Explanation: ndarray 也可以
End of explanation
b = np.random.randint(0,99, size=(5,10))
b
Explanation: Q3
動手試試看各種情況
比方
python
b = np.random.randint(0,99, size=(10,10))
b[::2, 2]
Fancy indexing
End of explanation
b[[1,3]]
b[(1,3)]
b[[1,2], [3,4]]
b[[(1,2),(3,4)]]
b[[True, False, False, True, False]]
Explanation: 試試看下面的結果
想一下是怎麼一回事(numpy 在想什麼？)
End of explanation
#參考範例
%run -i q4.py
Explanation: Q4
把 b 中的偶數都變成 -1
End of explanation
# 還記得剛才的
from PIL import Image
img = Image.open('img/Green-Rolling-Hills-Landscape-800px.png')
img_array = np.array(img)
Image.fromarray(img_array)
# 用來顯示圖片的函數
from IPython.display import display
def show(img_array):
    display(Image.fromarray(img_array))
Explanation: 用圖形來練習
End of explanation
# 將圖片縮小成一半
%run -i q_half.py
# 將圖片放大
%run -i q_scale2.py
# 圖片上下顛倒
show(img_array[::-1])
%run -i q_paste.py
%run -i q_grayscale.py
Explanation: Q
將圖片縮小成一半
擷取中間一小塊
圖片上下顛倒
左右鏡射
去掉綠色
將圖片放大兩倍
貼另外一張圖到大圖中
python
from urllib.request import urlopen
url = "https://raw.githubusercontent.com/playcanvas/engine/master/examples/images/animation.png"
simg = Image.open(urlopen(url))
紅綠交換
團片變成黑白 參考 Y=0.299R+0.587G+0.114B 
會碰到什麼困難？ 要如何解決
End of explanation
# 用迴圈畫圓
%run -i q_slow_circle.py
# 用 fancy index 畫圓
%run -i q_fast_circle.py
Explanation: Q
挖掉個圓圈？ (300,300)中心，半徑 100
旋轉九十度? x,y 互換？
End of explanation
# 還可以做模糊化
a = img_array.astype(float)
for i in range(10):
    a[1:,1:] = (a[1:,1:]+a[:-1,1:]+a[1:,:-1]+a[:-1,:-1])/4
show(a.astype('uint8'))
# 求邊界
a = img_array.astype(float)
a = a @ [0.299, 0.587, 0.114, 0]
a = np.abs((a[1:]-a[:-1]))*2
show(a.astype('uint8'))
Explanation: indexing 的其他用法
End of explanation
# reshaping 的應用
R,G,B,A = img_array.reshape(-1,4).T
plt.hist((R,G,B,A), color="rgby");
Explanation: Reshaping
.flatten 拉平看看資料在電腦中如何儲存？
查看
.reshape, .T, np.rot00, .swapaxes .rollaxis
然後再做一下上面的事情
End of explanation
# 例子
show(np.hstack([img_array, img_array2]))
# 例子
np.concatenate([img_array, img_array2], axis=2).shape
Explanation: 堆疊在一起
查看 np.vstack np.hstack np.concatenate 然後試試看
End of explanation
np.max([1,2,3,4])
np.sum([1,2,3,4])
np.mean([1,2,3,4])
np.min([1,2,3,4])
Explanation: 作用在整個 array/axis 的函數
End of explanation
x_mean = img_array.astype(float).min(axis=0, keepdims=True)
print(x_mean.dtype, x_mean.shape)
y_mean = img_array.astype(float).min(axis=1, keepdims=True)
print(y_mean.dtype, y_mean.shape)
# 自動 broadcast 
xy_combined = ((x_mean+y_mean)/2).astype('uint8')
show(xy_combined)
Explanation: 多重意義的運用， 水平平均，整合垂直平均
End of explanation
# = 1*4 + 2*5 + 4*6
np.dot([1,2,3], [4,5,6])
u=np.array([1,2,3])
v=np.array([4,5,6])
print( u@v )
print( (u*v).sum() )
Explanation: Tensor 乘法
先從點積開始
End of explanation
A=np.random.randint(0,10, size=(5,3))
A
B=np.random.randint(0,10, size=(3,7))
B
A.dot(B)
Explanation: 矩陣乘法
如果忘記矩陣乘法是什麼了， 參考這裡  http://matrixmultiplication.xyz/
或者 http://eli.thegreenplace.net/2015/visualizing-matrix-multiplication-as-a-linear-combination/
矩陣乘法可以看成是:
* 所有組合（其他軸）的內積（共有軸）
* 多個行向量線性組合
* 代入線性方程式 A1-矩陣與基本列運算.ipynb
* 用 numpy 來理解
python
np.sum(a[:,:, np.newaxis] * b[np.newaxis, : , :], axis=1)
dot(a, b)[i,k] = sum(a[i,:] * b[:, k])
高維度
要如何推廣？
* tensordot, tensor contraction, a.shape=(3,4,5), b.shape=(4,5,6), axis = 2 時等價於
python
np.sum(a[..., np.newaxis] * b[np.newaxis, ...], axis=(1, 2))
tensordot(a,b)[i,k]=sum(a[i, ...]* b[..., k])
https://en.wikipedia.org/wiki/Tensor_contraction
dot
python
dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
np.tensordot(a,b, axes=(-1,-2))
matmul 最後兩個 index 當成 matrix
python
a=np.random.random(size=(3,4,5))
b=np.random.random(size=(3,5,7))
(a @ b).shape
np.sum(a[..., np.newaxis] * np.moveaxis(b[..., np.newaxis], -1,-3), axis=-2)
einsum https://en.wikipedia.org/wiki/Einstein_notation
python
np.einsum('ii', a) # trace(a)
np.einsum('ii-&gt;i', a) #diag(a)
np.einsum('ijk,jkl', a, b) # tensordot(a,b)
np.einsum('ijk,ikl-&gt;ijl', a,b ) # matmul(a,b)
End of explanation
<END_TASK>