http://blog.csdn.net/pipisorry/article/details/39496831
numpy數組基本操作,包括copy, shape, 轉換(類型轉換), type, 重塑等等。這些操作應該都可以使用numpy.fun(array)或者array.fun()來調用。
皮皮blog
reshape(a, newshape[, order]) | Gives a new shape to an array without changing its data. |
ravel(a[, order]) | Return a contiguous flattened array. |
ndarray.flat | A 1-D iterator over the array.屬性,會改變原數組。 |
ndarray.flatten([order]) | Return a copy of the array collapsed into one dimension.方法,不會改變原數組。 |
Array的形態操作-numpy更改數組的形狀與數組堆疊
可以通過修改shape屬性,在保持數組元素個數不變的情況下,改變數組每個軸的長度。
下面的例子將數組c的shape改為(4,3),注意從(3,4)改為(4,3)并不是對數組進行轉置,而只是改變每個軸的大小,數組元素在內存中的位置并沒有改變:
>>> c.shape = 4,3>>> carray([[ 1, 2, 3], [ 4, 4, 5], [ 6, 7, 7], [ 8, 9, 10]])當某個軸的元素為-1時,將根據數組元素的個數自動計算此軸的長度,因此下面的程序將數組c的shape改為了(2,6):
>>> c.shape = 2,-1>>> carray([[ 1, 2, 3, 4, 4, 5], [ 6, 7, 7, 8, 9, 10]])使用數組的reshape方法,可以創建一個改變了尺寸的新數組,原數組的shape保持不變:
>>> d = a.reshape((2,2))>>> darray([[1, 2],[3, 4]])>>> aarray([1, 2, 3, 4])數組a和d其實共享數據存儲內存區域,因此修改其中任意一個數組的元素都會同時修改另外一個數組的內容!
>>> a[1] = 100 # 將數組a的第一個元素改為100>>> d # 注意數組d中的2也被改變了array([[ 1, 100], [ 3, 4]])Note: 需要注意的是,這里與MATLAB不一樣,MATLAB變換是按列向量來的,而NUMPY是基于行向量
[[ 1. 4. ] [ 2.2 5. ] [ 3. 6. ]]
a.reshape(6,1) -- 將3x2矩陣變成列向量(6x1)
所以numpy的運行結果為:
[[ 1. ] [ 4. ] [ 2.2] [ 5. ] [ 3. ] [ 6. ]] (列向量)
而MATLAB的運行結果為 : 1 2.2 3 4 5 6 (列向量)
注意: 對應的MATLAB很多向量默認為列向量,numpy中默認為行向量
numpy中多維數組轉換為一維向量 · flatten(): 復制一個一維的array出來
ndarray.reshape(-1) {shape: (4,)}
要注意的是reshape(返回?)后的數組不是原數組的復制,reshape前后的數組指向相同的地址(只是維度重新定義了一下)也可以用flatten函數將高維數組轉化為向量,和reshape不同的是,flatten函數會生成原始數組的復制
In [40]: a = np.array([[2,2], [2,3]])In [41]: a.flatten()Out[41]: array([2, 2, 2, 3])In [43]: a.reshape(-1)Out[43]: array([2, 2, 2, 3])但是像這種不規則維度的多維數組就不能轉換成功了,還是本身 a = np.array([[[2,3]], [2,3]])
轉換成二維表示的一維數組 a.reshape(1, -1) {(1, 4)}
兩者的區別
import numpy as npa = np.array([1, 2, 3])b = a.reshape(1, -1)PRint(b)print(b.shape)c = a.reshape(-1)print(c)print(c.shape)[[1 2 3]](1, 3)[1 2 3](3,).ravel() # flatten the array
· resize(): 也是改變array的形態。不同的是,resize是直接修改這個對象的,而reshape則會生成一個新的對象
flatten操作只是針對規則shape的ndarray,如果是不規則的列表可以使用自定義的flatten函數
flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) in [tuple, list, np.ndarray] else [x]a = [[1, 2], 5, [6], (7, 8), (9)]print(flatten(a))[1, 2, 5, 6, 7, 8, 9][Python模塊 - itertools循環器模塊]
皮皮blog
Transpose-like operations
rollaxis(a, axis[, start]) | Roll the specified axis backwards, until it lies in a given position. |
swapaxes(a, axis1, axis2) | Interchange two axes of an array. |
ndarray.T | Same as self.transpose(), except that self is returned if self.ndim < 2. |
transpose(a[, axes]) | Permute the dimensions of an array. |
· swapaxes(): 將n個維度中任意兩個維度(坐標軸)進行調換
· transpose(): 這個就是矩陣的轉置操作
第二個參數為需要調整位置的軸,第三個參數為目標位置。
axis : int The axis to roll backwards. The positions of the other axes do notchange relative to one another.
start : int, optional The axis is rolled until it lies before this position. The default,0, results in a “complete” roll.
這個函數看半天才懂!
就是將axis維度轉換到start(默認0)維度上。
在很多計算上會減少相當多的操作。如三維array在axis=2維度上去除均值。
def z_score(x, axis): x = np.array(x).astype(float) xr = np.rollaxis(x, axis=axis) print(xr) xr -= np.mean(x, axis=axis) return xx = [[[10, 20], [30, 40]], [[50, 60], [70, 80]]]print(np.array(x))z_score(x, 2)[[[10 20] [30 40]] [[50 60] [70 80]]][[[ 10. 30.] [ 50. 70.]] [[ 20. 40.] [ 60. 80.]]]
其轉換是這樣的:
這樣轉換之后,并不會影響原來x的維度,但會影響x的值,但是在減去x對應axis軸上的均值時會通過廣播規則正確使轉換后array減去其均值。
其實這個過程就相當于將reshape然后通過廣播規則減去均值,再reshape回來。但是這個函數明顯在多維時更有優勢,因為多維時的reshape你搞得清楚嗎?
Changing number of dimensions
atleast_1d(*arys) | Convert inputs to arrays with at least one dimension. |
atleast_2d(*arys) | View inputs as arrays with at least two dimensions. |
atleast_3d(*arys) | View inputs as arrays with at least three dimensions. |
broadcast | Produce an object that mimics broadcasting. |
broadcast_to(array, shape[, subok]) | Broadcast an array to a new shape. |
broadcast_arrays(*args, **kwargs) | Broadcast any number of arrays against each other. |
expand_dims(a, axis) | Expand the shape of an array. |
squeeze(a[, axis]) | Remove single-dimensional entries from the shape of an array. |
也就是將所有維度為1的維度去掉。這個操作應該等價于a.reshape(-1)。
scipy.spatial.distance.euclidean()函數源碼:
u = np.asarray(u, dtype=dtype, order='c').squeeze()# Ensure values such as u=1 and u=[1] still return 1-D arrays.使用示例1
In [54]: a = np.array([[2,2], [2,3]])In [55]: aarray([[2, 2], [2, 3]])In [56]: a = a.reshape(1, -1)In [57]: aarray([[2, 2, 2, 3]])In [58]: a.shape (1, 4)In [59]: a.squeeze().shape(4,)
使用示例2
In [19]: x = np.array([[[0], [1], [2]]])In [20]: np.squeeze(x) #或者x.squeeze()Out[20]: array([0, 1, 2])In [21]: x.shapeOut[21]: (1, 3, 1)In [22]: np.squeeze(x).shapeOut[22]: (3,)
Changing kind of array
asarray(a[, dtype, order]) | Convert the input to an array. |
asanyarray(a[, dtype, order]) | Convert the input to an ndarray, but pass ndarray subclasses through. |
asmatrix(data[, dtype]) | Interpret the input as a matrix. |
asfarray(a[, dtype]) | Return an array converted to a float type. |
asfortranarray(a[, dtype]) | Return an array laid out in Fortran order in memory. |
ascontiguousarray(a[, dtype]) | Return a contiguous array in memory (C order). |
asarray_chkfinite(a[, dtype, order]) | Convert the input to an array, checking for NaNs or Infs. |
asscalar(a) | Convert an array of size 1 to its scalar equivalent. |
require(a[, dtype, requirements]) | Return an ndarray of the provided type that satisfies requirements. |
皮皮blog
concatenate((a1, a2, ...)[, axis]) | Join a sequence of arrays along an existing axis. |
stack(arrays[, axis]) | Join a sequence of arrays along a new axis. |
column_stack(tup) | Stack 1-D arrays as columns into a 2-D array. |
dstack(tup) | Stack arrays in sequence depth wise (along third axis). |
hstack(tup) | Stack arrays in sequence horizontally (column wise). |
vstack(tup) | Stack arrays in sequence vertically (row wise). |
numpy更改數組的形狀與數組堆疊
函數原型:numpy.concatenate((a1, a2, ...), axis=0)
函數原型:numpy.stack(arrays, axis=0)
對那些維度比二維更高的數組,hstack沿著第二個軸組合,vstack沿著第一個軸組合,concatenate允許可選參數給出組合時沿著的軸。
函數原型:numpy.hstack(tup)
其中tup是arrays序列,The arrays must have the same shape, except in the dimensioncorresponding toaxis (the first, by default).
等價于:np.concatenate(tup, axis=1)函數原型:numpy.vstack(tup)
等價于:np.concatenate(tup, axis=0) if tup contains arrays thatare at least 2-dimensional.
new_matrix=np.hstack([mat1,mat2]) 或按行合并矩陣(要求兩矩陣列數一樣):new_matrix=np.vstack([mat1,mat2]) 合并矩陣的命令同樣可以用于合并向量,但是合并向量的時候有時會提示行列數不對,那可能是因為一個的維度是(n個),而另一個的維度是(n列,1行),這種情況下,可用reshape來進行轉換:
array2=array2.reshape(n)
new_array=np.hstack([array1,array2])
Note:函數column_stack以列將一維數組合成二維數組,它等同與vstack對一維數組。row_stack函數,另一方面,將一維數組以行組合成二維數組。
對那些維度比二維更高的數組,hstack沿著第二個軸組合,vstack沿著第一個軸組合,concatenate允許可選參數給出組合時沿著的軸。在復雜情況下,r_[]和c_[]對創建沿著一個方向組合的數很有用,它們允許范圍符號(“:”):>>> r_[1:4,0,4]array([1, 2, 3, 0, 4])當使用數組作為參數時,r_和c_的默認行為和vstack和hstack很像,但是允許可選的參數給出組合所沿著的軸的代號。
Note: numpy.hstack()和numpy.column_stack()函數略有相似,numpy.vstack()與numpy.row_stack()函數也是挺像的。
[numpy vstack vs. column_stack]
在數組的第三個軸(即深度)上組合,對應的元素都組合成一個新的列表,該列表作為新的數組的元素。This is a simple way to stack 2D arrays (images) into a single 3D array for processing.
函數原型:numpy.dstack(tup)等價于:np.concatenate(tup, axis=2)
x, y = np.meshgrid(np.linspace(-1, 1, 3), np.linspace(-1, 1, 3))print('x=/n', x)print('y=/n',y)print('stack = /n', np.dstack((x, y)))x= [[-1. 0. 1.] [-1. 0. 1.] [-1. 0. 1.]]y= [[-1. -1. -1.] [ 0. 0. 0.] [ 1. 1. 1.]]stack = [[[-1. -1.] [ 0. -1.] [ 1. -1.]] [[-1. 0.] [ 0. 0.] [ 1. 0.]] [[-1. 1.] [ 0. 1.] [ 1. 1.]]]可以看成是兩個二維坐標值組合成三維坐標,可用于三維圖形繪制。[三維繪圖之matplotlib.mplot3d工具包]行組合row_stack
行組合可將多個一維數組作為新數組的每一行進行組合
>>> one = arange(2) >>> one array([0, 1]) >>> two = one + 2 >>> two array([2, 3]) >>> row_stack((one, two)) array([[0, 1], [2, 3]]) 對于2維數組,其作用就像垂直組合一樣。
列組合column_stack
>>> column_stack((oned, twiceoned)) array([[0, 2], [1, 3]]) 對于2維數組,其作用就像水平組合一樣。
不同stack函數使用示例
In [3]: a = np.array([1, 2, 3])In [4]: b = np.array([2, 3, 4]) In [6]: print(a)[1 2 3]In [7]: print(b)[2 3 4]>>> np.stack((a, b)) array([[1, 2, 3], [2, 3, 4]])>>> np.vstack((a,b)) array([[1, 2, 3], [2, 3, 4]])>>> np.hstack((a,b)) array([1, 2, 3, 2, 3, 4])>>> np.dstack((a,b)) array([[[1, 2], [2, 3], [3, 4]]])In [8]: a = np.array([[1], [2], [3]])In [9]: b = np.array([[2], [3], [4]])In [11]: print(a)[[1] [2] [3]]In [12]: print(b)[[2] [3] [4]]>>> np.stack((a, b), axis=-1) array([[1, 2], [2, 3], [3, 4]]) >>> np.vstack((a,b))array([[1], [2], [3], [2], [3], [4]])In [14]: np.hstack((a,b))array([[1, 2], [2, 3], [3, 4]])In [15]: np.dstack((a,b))array([[[1, 2]], [[2, 3]], [[3, 4]]])#不處理xy的最后一列xy = np.hstack([preprocessing.scale(xy[:, 0:-1]), xy[:, -1].reshape(-1, 1)])[NumPy簡明教程(二、數組3)]
[Python numpy函數hstack() vstack() stack() dstack() vsplit() concatenate()]
皮皮blog
Splitting arrays
split(ary, indices_or_sections[, axis]) | Split an array into multiple sub-arrays. |
array_split(ary, indices_or_sections[, axis]) | Split an array into multiple sub-arrays. |
dsplit(ary, indices_or_sections) | Split array into multiple sub-arrays along the 3rd axis (depth). |
hsplit(ary, indices_or_sections) | Split an array into multiple sub-arrays horizontally (column-wise). |
vsplit(ary, indices_or_sections) | Split an array into multiple sub-arrays vertically (row-wise). |
tile(A, reps) | Construct an array by repeating A the number of times given by reps. |
repeat(a, repeats[, axis]) | Repeat elements of an array. |
模板numpy.lib.shape_base中的函數。
函數的形式是tile(A,reps)
A和reps都是array_like的,幾乎所有類型都可以:array, list, tuple, dict, matrix以及基本數據類型int,string, float以及bool類型。reps的類型也很多,可以是tuple,list, dict, array, int,bool.但不可以是float,string, matrix類型。就是重塑后新數組A的對應維上重復多少次,并且從高維開始?A的維度d > len(reps)時當d>=len時,將reps長度補足為d,即在reps前面加上d-len個1。(其實就是層不重復,而對里層重復!)這里的意思是,假設A為k維數組,每一維都有一定長度,新的A構成的維度向量為D。Note:相乘的意思為,將原來A中每一維度的元素進行copy,生成的A中此元素出現次數為新的reps對應維度的數目。操作從低維度向高維進行。
>>> tile([[1,2,3],[4,5,5]],2)array([[1, 2, 3, 1, 2, 3],W = np.tile([[3,5,6]],[3,1])print(W)[[3 5 6] [3 5 6] [3 5 6]]A的維度d < len(reps)時>>> tile([1,2,3],[2,2,2,2])array([[[[1, 2, 3, 1, 2, 3],[1, 2, 3, 1, 2, 3]], [[1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3]]], [[[1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3]], [[1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3]]]]) Note:A的維度d=1 < len(reps)=4,這樣A在0維(最外層的[])上每個元素都copy為2倍,在1維上每個元素都copy為2倍,在2維上每個元素都copy為2倍,在3維上每個元素都copy為2倍。最后形成一個4維的array。
[Numpy的tile函數]
repeat
repeat(6,axis=0)表示的是將a按照第一軸的方向擴展6次得到的數組。axis=0表示的是按照第一軸的方向操作,也就是列方向上;若是axis=1就是行方向上面;這個也是等價于axis=-1的。因為-1表示的是它的最后那個軸方向。所以也就是行方向上面。
皮皮blog
Adding and removing elements
delete(arr, obj[, axis]) Return a new array with sub-arrays along an axis deleted. insert(arr, obj, values[, axis]) Insert values along the given axis before the given indices. append(arr, values[, axis]) Append values to the end of an array. resize(a, new_shape) Return a new array with the specified shape. trim_zeros(filt[, trim]) Trim the leading and/or trailing zeros from a 1-D array or sequence. unique(ar[, return_index, return_inverse, ...]) Find the unique elements of an array. append函數
(將一個列表加入多維數組ndarray中; 實現matlab data=[data1;data2]的功能)
data1 = random.randint(1, 10, (2, 3))data2 = random.randint(-10, -1, (2, 3))data = append(data1, data2, axis=0)print(data1)print(data2)print()print(data)[[1 3 7] [8 3 3]][[ -3 -8 -6] [ -3 -10 -10]][[ 1 3 7] [ 8 3 3] [ -3 -8 -6] [ -3 -10 -10]]Rearranging elements
fliplr(m) Flip array in the left/right direction. flipud(m) Flip array in the up/down direction. reshape(a, newshape[, order]) Gives a new shape to an array without changing its data. roll(a, shift[, axis]) Roll array elements along a given axis. rot90(m[, k]) Rotate an array by 90 degrees in the counter-clockwise direction. 皮皮blog
廣播規則
廣播規則允許你在形狀不同但卻兼容的數組上進行計算。換句話說,你并不總是需要重塑或鋪平數組,使它們的形狀匹配。
廣播規則描述了具有不同維度和/或形狀的數組仍可以用于計算。一般的規則是:當兩個維度相等,或其中一個為1時,它們是兼容的。NumPy使用這個規則,從后邊的維數開始,向前推導,來比較兩個元素級數組的形狀。最小的維度在內部被自動延伸,從而匹配其他維度,但此操作并不涉及任何內存復制。
下面的例子說明了兩個向量之間進行矢量積的兩個方法:第一個方法涉及到數組的變形操作,第二個方法涉及到廣播規則。顯然第二個方法是要快得多。
[python] view plain copy print?n =1000 a =np.arange(n) ac =a[:, np.newaxis] ar =a[np.newaxis, :] %timeit np.tile(ac, (1, n))* np.tile(ar, (n,1)) 100 loops, best of 3:10 ms per loop %timeit ar* ac 100 loops, best of 3:2.36 ms per loop
廣播(broadcasting)運算及數組四則運算
當使用ufunc函數對兩個數組進行計算時,ufunc函數會對這兩個數組的對應元素進行計算,因此它要求這兩個數組的形狀相同。
廣播規則允許你在形狀不同但卻兼容的數組上進行計算。換句話說,你并不總是 需要重塑或鋪平數組,使它們的形狀匹配。
廣播規則描述了具有不同維度和/或形狀的數組仍可以用于計算。一般的規則是:當兩個維度相等,或其中一個為1時,它們是兼容的。NumPy使用這個規則,從后邊的維數開始,向前推導,來比較兩個元素級數組的形狀。最小的維度在內部被自動延伸,從而匹配其他維度,但此操作并不涉及任何內存復制。
如果形狀不同,會進行如下的廣播處理:讓所有輸入數組都向其中維數最多的數組看齊,shape屬性中不足的部分都通過在前面加1補齊。輸出數組的shape屬性是輸入數組的shape屬性的各個軸上的最大值。如果輸入數組的某個軸的長度為1或與輸出數組的對應軸的長度相同時,這個數組能夠用來計算,否則出錯。當輸入數組的某個軸的長度為1時,沿著此軸運算時都用此軸上的第一組值。例子
為了更好的了解廣播運算可以先看看前面的tile函數的計算方式。
例1:2*1數組和1*2數組相乘
a = np.array([1, 2]).reshape([-1, 1])print('a = /n', a)b = np.array([[4, 5]])print('b = /n', b)print('a*b = /n', a * b)a = [[1] [2]]b = [[4 5]]a*b = [[ 4 5] [ 8 10]]例2:先創建一個二維數組a,其形狀為(6,1):
>>> a = np.arange(0, 60, 10).reshape(-1, 1)>>> aarray([[ 0], [10], [20], [30], [40], [50]])>>> a.shape(6, 1)再創建一維數組b,其形狀為(5,):
>>> b = np.arange(0, 5)>>> barray([0, 1, 2, 3, 4])>>> b.shape(5,)例1:計算a和b的和
得到一個加法表,它相當于計算兩個數組中所有元素組的和,得到一個形狀為(6,5)的數組:
>>> c = a + b>>> carray([[ 0, 1, 2, 3, 4], [10, 11, 12, 13, 14], [20, 21, 22, 23, 24], [30, 31, 32, 33, 34], [40, 41, 42, 43, 44], [50, 51, 52, 53, 54]])>>> c.shape(6, 5)由于a和b的維數不同,根據規則1,需要讓b的shape屬性向a對齊,于是將b的shape屬性前面加1,補齊為(1,5)。相當于做了如下計算:
>>> b.shape=1,5>>> barray([[0, 1, 2, 3, 4]])這樣加法運算的兩個輸入數組的shape屬性分別為(6,1)和(1,5),根據規則2,輸出數組的各個軸的長度為輸入數組各個軸的長度的最大值,可知輸出數組的shape屬性為(6,5)。
由于b的第0軸的長度為1,而a的第0軸的長度為6,為了讓它們在第0軸上能夠相加,需要將b的第0軸的長度擴展為6,這相當于:
>>> b = b.repeat(6,axis=0)>>> barray([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]])由于a的第1軸的長度為1,而b的第1軸長度為5,為了讓它們在第1軸上能夠相加,需要將a的第1軸的長度擴展為5,這相當于:
>>> a = a.repeat(5, axis=1)>>> aarray([[ 0, 0, 0, 0, 0], [10, 10, 10, 10, 10], [20, 20, 20, 20, 20], [30, 30, 30, 30, 30], [40, 40, 40, 40, 40], [50, 50, 50, 50, 50]])經過上述處理之后,a和b就可以按對應元素進行相加運算了。
但是不能整除的就不能進行廣播運算了。如ValueError: operands could not be broadcast together with shapes (3,5) (3,) 。
例2:行減行均值
A = np.array([[1, 2, 3, 4, 5], [2, 3, 2, 5, 3], [5, 5, 5, 3, 2]])print(A)row_mean = np.mean(A, 1).reshape([len(A),1])print(row_mean)print(A - row_mean)當然,在執行“a+b”運算時,NumPy內部并不會真正將長度為1的軸用repeat()進行擴展,這樣太浪費空間了。
Note: 二維列減列和三維表減表均值就沒有問題x-np.mean(x, axis=0),計算出來的就是x對應的元素減去其對應均值。
例3:三維行減行均值的案例分析axis=2
lz發現不能使用x-np.mean(x, axis)來計算某array x的去均值array
如一個2*2*2的array: x = [[[10,20], [30,40]], [[50,60], [70, 80]]]
x =
[[[10 20] [30 40]] [[50 60] [70 80]]]
np.mean(x, axis=2)
[[ 15. 35.] [ 55. 75.]]
x -=np.mean(x,axis=2)
[[[ -5. -15.] [-25. -35.]] [[ 35. 25.] [ 15. 5.]]]
并不是我們想要的結果。
因為廣播規則計算x -=np.mean(x,axis=2)時拓展的是np.mean(x,axis=2)的0維(x是2*2*2而拓展np.mean(x,axis=2)為1*2*2,再復制0維為2*2*2)
解決方式1:
sklearn preprocessing.scale(x, axis=2)可以解決這個問題,但是3維默認是不可以歸一化的, 要修改一下源碼
將X = check_array(X,accept_sparse='csc',copy=copy,ensure_2d=False,warn_on_dtype=True,estimator='the scale function',dtype=FLOAT_DTYPES) 刪除并
加上x = np.array(x).astype(float)
解決方式2:
x = np.array(x).astype(float)xr = np.rollaxis(x, axis=axis)xr -= np.mean(x, axis=axis)[[[-5. 5.] [-5. 5.]] [[-5. 5.] [-5. 5.]]]
快速產生廣播運算數組的ogrid對象
[numpy教程:數組創建]
from: http://blog.csdn.net/pipisorry/article/details/39496831
ref: Array manipulation routines
新聞熱點
疑難解答