5&6.numpy陣列的基本操作
import numpy as np
x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
X = np.arange(15).reshape(3, 5)
X
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
基本屬性
x.ndim
#檢視陣列維度
1
X.ndim
2
x.shape
#返回型別是一個元組。說明該陣列是一維陣列,包含10個元素
(10,)
X.shape
#說明該陣列是二維陣列,3行5列
(3, 5)
x.size
#表示元素個數
10
X.size
15
numpy.array資料的訪問
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[3]
3
x[-1]
9
X[2, 3]
#numpy中建議這種形式的資料索引
13
x[0:5]
#切片操作,不包含終止位
array([0, 1, 2, 3, 4])
x[4:]
array([4, 5, 6, 7, 8, 9])
x[:]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
#也可加入步長
x[::2]
array([0, 2, 4, 6, 8])
x[0:7:2]
array([0, 2, 4, 6])
X
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
# 取X的前2行前3列
X[:2, :3]
array([[0, 1, 2],
[5, 6, 7]])
#不可以用X[:2][:3]的格式,這是取了X[:2]這個陣列中的前三個元素結果如下,而X[:2]中只有兩個元素,所以只取到了如下的結果
X[:2]
X[:2][:3]
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
#訪問矩陣的前2行中,每行步長為2的元素 X[:2, ::2]
array([[0, 2, 4],
[5, 7, 9]])
X[::-1, ::-1]
#將整個矩陣翻轉過來
array([[14, 13, 12, 11, 10],
[ 9, 8, 7, 6, 5],
[ 4, 3, 2, 1, 0]])
X[0]
array([0, 1, 2, 3, 4])
X[0, :]
#只取第一行
array([0, 1, 2, 3, 4])
X[0, :].ndim
#此時的X[0, :]為一維陣列
1
X[:, 0]
#只取第一列
array([ 0, 5, 10])
X[:, 0].ndim
1
子矩陣的修改會影響到原矩陣
subX = X[:2, :3]
subX
array([[0, 1, 2],
[5, 6, 7]])
subX[0, 0] = 888
subX
array([[888, 1, 2],
[ 5, 6, 7]])
X
array([[888, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[ 10, 11, 12, 13, 14]])
同樣原矩陣修改也會影響子矩陣
X[0, 0] = 0
X
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
subX
array([[0, 1, 2],
[5, 6, 7]])
要想子矩陣和原矩陣互不影響,呼叫格式為 subX = X[:2, :3].copy()
subX = X[:2, :3].copy()
subX
array([[0, 1, 2],
[5, 6, 7]])
subX[0, 0] = 888
subX
array([[888, 1, 2],
[ 5, 6, 7]])
X
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
reshape
x.shape
#x是一位陣列,只有10個元素
(10,)
#把x變成一個2行5列的矩陣
x.reshape(2, 5)
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
使用reshape函式並沒有改變x陣列本身
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
想要保留這種改變,則需要另一個變數來承接
a = x.reshape(2, 5)
a
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
也可以將x修改為一個二維的陣列
b = x.reshape(1, 10)
b
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
注意此時的陣列中是2個方括號
b.shape
(1, 10)
b.ndim
2
只指定行數,而不指定列數,可以用如下呼叫格式
b = x.reshape(10, -1)
b
array([[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])
b = x.reshape(2, -1)
b
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
同理只指定列數,而不指定行數,可以用如下呼叫格式
b = x.reshape(-1, 10)
b
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
b = x.reshape(-1, 5)
b
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
合併操作
x = np.array([1, 2, 3])
x
array([1, 2, 3])
y = np.array([4, 5, 6])
y
array([4, 5, 6])
#拼接操作
np.concatenate([x, y])
array([1, 2, 3, 4, 5, 6])
# 也可以拼接三個陣列
z = np.array([88, 88, 88])
np.concatenate([x, y, z])
array([ 1, 2, 3, 4, 5, 6, 88, 88, 88])
二維陣列的拼接
A = np.array([[1, 2, 3],
[4, 5, 6]])
A
array([[1, 2, 3],
[4, 5, 6]])
np.concatenate([A, A])
#預設是按照行來拼接
# 可以理解為矩陣A有2個樣本,每個樣本有三個特徵值,拼接後變為4個樣本
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3],
[4, 5, 6]])
np.concatenate([A, A], axis = 1)
#預設的axis = 0,按行拼接,axis = 1,按列拼接
array([[1, 2, 3, 1, 2, 3],
[4, 5, 6, 4, 5, 6]])
二維陣列和一維陣列不能直接用np.concatenate拼接,因為維度不同,所以需要使用reshape
B = np.concatenate([A, z.reshape(1, -1)])
B
array([[ 1, 2, 3],
[ 4, 5, 6],
[88, 88, 88]])
也可以使用np.vstack()進行直接拼接
B = np.vstack([A, z])
#v表示vertical豎直方向拼接
B
array([[ 1, 2, 3],
[ 4, 5, 6],
[88, 88, 88]])
np.hstack() 水平方向的拼接
B = np.full(shape = (2, 2), fill_value = 555)
B
array([[555, 555],
[555, 555]])
np.hstack([A, B])
array([[ 1, 2, 3, 555, 555],
[ 4, 5, 6, 555, 555]])
分割操作
a = np.arange(10)
a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a1, a2, a3 = np.split(a, [3, 7])
#np.split()中第一個引數是切割物件,第二個引數是切割點
#[3, 7]表示0-3, 3-7, 7-9,包前不包後
a1
array([0, 1, 2])
a2
array([3, 4, 5, 6])
a3
array([7, 8, 9])
a1, a2 = np.split(a, [5])
a1
array([0, 1, 2, 3, 4])
a2
array([5, 6, 7, 8, 9])
分割二維陣列
A = np.arange(16).reshape(4, 4)
A
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
A1, A2 = np.split(A, [1])
#分割矩陣的行
A1
array([[0, 1, 2, 3]])
A2
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
A1, A2 = np.split(A, [1], axis = 1)
#axis預設為0,分割行,axis = 1,分割列
A1
array([[ 0],
[ 4],
[ 8],
[12]])
A2
array([[ 1, 2, 3],
[ 5, 6, 7],
[ 9, 10, 11],
[13, 14, 15]])
豎直分割矩陣和水平分割矩陣
upper, lower = np.vsplit(A, [1])
upper
array([[0, 1, 2, 3]])
lower
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
left, right = np.hsplit(A, [3])
left
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10],
[12, 13, 14]])
right
array([[ 3],
[ 7],
[11],
[15]])
資料分割的意義在於,分割樣本特徵值和標籤
data = np.arange(16).reshape(4, 4)
data
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
#例如最後一列是標籤
x, y = np.hsplit(data, [-1])
x
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10],
[12, 13, 14]])
y
array([[ 3],
[ 7],
[11],
[15]])
y[:, 0]
array([ 3, 7, 11, 15])