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。而长度为len的reps有len个数,进行tile函数运算时补足d位,前面加d-len个1,如下图所示:经过tile运算,生成新的A,A的各维维度为: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
新闻热点
疑难解答