reshape
无需复制任何数据,数组就能从一个形状转换成另一个形状。 ——向数组的实例方法reshape
传入一个表示新形状的元组。
ravel
散开 flatten
扁平化注意: ravel
不会产生源数据的副本,相反,flatten
总是返回数据的副本。
np.concatenate()
np.vstack()
np.hstack()
In [2]: import numpy as np
In [3]: arr1 = np.array([[1,2,3],[4,5,6]])
In [4]: arr2 = np.array([[7,8,9],[10,11,12]])
In [5]: np.concatenate([arr1,arr2], axis=0)
Out[5]:
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
In [6]: np.vstack((arr1,arr2))
Out[6]:
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
In [7]: np.concatenate([arr1,arr2], axis=1)
Out[7]:
array([[ 1, 2, 3, 7, 8, 9],
[ 4, 5, 6, 10, 11, 12]])
In [8]: np.hstack((arr1,arr2))
Out[8]:
array([[ 1, 2, 3, 7, 8, 9],
[ 4, 5, 6, 10, 11, 12]])
split
:沿指定轴在指定的位置拆分数组。
In [19]: from numpy.random import randn
In [20]: arr = randn(5,2)
In [21]: arr
Out[21]:
array([[-0.24213657, 0.7912939 ],
[-1.93341047, -0.090163 ],
[-1.44827594, -0.77660436],
[-0.35056947, 0.96571127],
[ 1.02953072, 1.4517834 ]])
In [22]: first, second, third = np.split(arr,[1,3])
In [23]: first
Out[23]: array([[-0.24213657, 0.7912939 ]])
In [24]: second
Out[24]:
array([[-1.93341047, -0.090163 ],
[-1.44827594, -0.77660436]])
In [25]: third
Out[25]:
array([[-0.35056947, 0.96571127],
[ 1.02953072, 1.4517834 ]])
函数 | 说明 |
---|---|
concatenate | 最一般化的连接,沿一条轴连接一组数组 |
vstack、row_stack | 以面对行的方式对数组进行堆叠(沿轴0) |
hstack | 以面对列的方式对数组进行堆叠(沿轴1) |
column_stack | 类似于hstack,但是会先将一维数组转换为二维列向量 |
dstack | 以面向深度的方式对数组进行堆叠(沿轴2) |
split | 沿指定轴在指定位置拆分数组 |
hsplit、vsplit、dsplit | split的便捷化函数,分别沿轴0、1、2进行拆分 |
# 乘法运算中,标量值4被广播到了其他所有的元素上。
In [4]: arr = np.arange(5)
In [5]: arr
Out[5]: array([0, 1, 2, 3, 4])
In [6]: arr * 4
Out[6]: array([ 0, 4, 8, 12, 16])
# 通过减去列平均值的方式对数组的每一列进行距平化处理。
In [7]: arr = np.random.randn(4,3)
In [8]: arr
Out[8]:
array([[-0.02670178, 0.35390654, 2.55570361],
[ 0.31655488, 0.84301258, 0.91673203],
[-0.86669646, 0.50996979, -0.45762143],
[-0.50018861, -0.12417934, 1.28628869]])
In [9]: arr.mean(0)
Out[9]: array([-0.26925799, 0.39567739, 1.07527573])
# 一维数组在轴0上的广播(列,按行进行)
In [10]: demeaned = arr - arr.mean(0)
In [11]: demeaned
Out[11]:
array([[ 0.24255621, -0.04177085, 1.48042789],
[ 0.58581288, 0.44733519, -0.1585437 ],
[-0.59743847, 0.11429239, -1.53289716],
[-0.23093062, -0.51985673, 0.21101297]])
In [12]: demeaned.mean(0)
Out[12]: array([ 0.00000000e+00, 2.77555756e-17, 1.11022302e-16])
In [17]: arr
Out[17]:
array([[-0.02670178, 0.35390654, 2.55570361],
[ 0.31655488, 0.84301258, 0.91673203],
[-0.86669646, 0.50996979, -0.45762143],
[-0.50018861, -0.12417934, 1.28628869]])
In [18]: row_means = arr.mean(1)
In [19]: row_means
Out[19]: array([ 0.96096946, 0.69209983, -0.27144937, 0.22064025])
In [20]: row_means.reshape((4,1))
Out[20]:
array([[ 0.96096946],
[ 0.69209983],
[-0.27144937],
[ 0.22064025]])
# 在轴1上做减法(即各行减去平均值)
In [21]: demeaned = arr - row_means.reshape((4,1))
In [22]: demeaned.mean(1)
Out[22]:
array([ 0.00000000e+00, 0.00000000e+00, 3.70074342e-17,
0.00000000e+00])
广播的原则 : 如果两个数组的后缘维度的轴长相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在++缺失或长度为1++的维度上进行。
根据广播的原则,较小数组的“广播维”必须为1。
普遍的问题:需要专门为了广播添加一个长度为1的新轴。reshape插入轴需要构造一个表示新形状的元组。
因此,Numpy数组提供了一种通过索引机制插入轴的特殊语法:np.newaxis
属性以及“全”切片。
In [22]: arr = np.zeros((4,4))
In [23]: arr
Out[23]:
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
In [24]: arr_3d = arr[:,np.newaxis,:]
In [25]: arr_3d.shape
Out[25]: (4L, 1L, 4L)
In [26]: arr_3d
Out[26]:
array([[[ 0., 0., 0., 0.]],
[[ 0., 0., 0., 0.]],
[[ 0., 0., 0., 0.]],
[[ 0., 0., 0., 0.]]])
例子:对三维数组对轴二进行距平化
In [1]: import numpy as np
In [2]: arr = np.random.randn(3,4,5)
In [3]: depth_means = arr.mean(2)
In [4]: depth_means
Out[4]:
array([[ 0.8264348 , 0.42729857, -0.70614215, 0.41029565],
[ 0.04613014, -0.29223305, 0.1984838 , 0.30052865],
[-0.44228584, -0.50591049, 0.25722958, -0.00410482]])
In [5]: demeaned = arr - depth_means[:,:,np.newaxis]
In [6]: demeaned.mean(2)
Out[6]:
array([[ -1.33226763e-16, 4.44089210e-17, -2.22044605e-17,
-2.22044605e-17],
[ 0.00000000e+00, 4.44089210e-17, -4.44089210e-17,
-2.22044605e-17],
[ 0.00000000e+00, 4.44089210e-17, -2.22044605e-17,
-8.88178420e-17]])
对指定轴进行距平化的一种通用又不牺牲性能的方法:
def demean_axis(arr, axis=0):
means = arr.mean(axis)
#下面的类似于N维的[:,:,np.newaxis]
indexer = [slice(None)] * arr.ndim
indexer[axis] = np.newaxis
return arr - means(indexer)
In [11]: arr = np.zeros((4,3))
In [12]: arr[:] = 5
In [13]: arr
Out[13]:
array([[ 5., 5., 5.],
[ 5., 5., 5.],
[ 5., 5., 5.],
[ 5., 5., 5.]])
In [14]: col = np.array([1.28,-0.42,0.44,1.6])
In [15]: arr[:] = col[:,np.newaxis]
In [16]: arr
Out[16]:
array([[ 1.28, 1.28, 1.28],
[-0.42, -0.42, -0.42],
[ 0.44, 0.44, 0.44],
[ 1.6 , 1.6 , 1.6 ]])
In [17]: arr[:2] = [[-1.37],[0.59]]
In [18]: arr
Out[18]:
array([[-1.37, -1.37, -1.37],
[ 0.59, 0.59, 0.59],
[ 0.44, 0.44, 0.44],
[ 1.6 , 1.6 , 1.6 ]])
方法 | 说明 |
---|---|
reduce(x) | 通过连续执行原始运算的方式对值进行聚合 |
accumulate(x) | 聚合值,保留所有局部聚合结果 |
reduceat(x,bins) | “局部”约简(也就是groupby)。约减数据的各个切片以产生聚合型数组 |
outer(x,y) | 对x,y的每对原始应用原始运算。结果数组的形状为x.shape + y.shape |
例子:
arr = np.arange(10)
np.add.reduce(arr) #45
np.add.accumulate(arr1, axis=1) # 产生一个跟原始数组大小相同的中间“累计”值数组
np.multiply.outer(arr2, np.arange(5)) #计算两个数组的叉积
np.add.reduceat(arr3, [0,5,8]) #计算局部约简,接受一组用于指示如何对值进行拆分和聚合的“边界”
结构化数组是一种特殊的ndarray。用于表示异质或表格型的数据。
定义结构化dtype, 典型方法是元组列表,各个元组的格式为(field_name, field_data_type)。
In [1]: import numpy as np
In [2]: dtype = [('x', np.float64), ('y', np.int32)]
In [3]: sarr = np.array([(1.5,6),(np.pi,-2)],dtype=dtype)
In [4]: sarr
Out[4]:
array([(1.5, 6), (3.141592653589793, -2)],
dtype=[('x', '), ('y', ')])
In [5]: sarr[0]
Out[5]: (1.5, 6)
In [6]: sarr[0]['y']
Out[6]: 6
In [7]: sarr['x']
Out[7]: array([ 1.5 , 3.14159265])
In [13]: dtype = [('x', [('a', 'f8'), ('b', 'f4')]), ('y', np.int32)]
In [14]: arr = np.array([((1,2),5), ((3,4),6)])
In [15]: arr = np.array([((1,2),5), ((3,4),6)], dtype=dtype)
In [16]: arr['x']
Out[16]:
array([(1.0, 2.0), (3.0, 4.0)],
dtype=[('a', '), ('b', ')])
In [17]: arr['y']
Out[17]: array([5, 6], dtype=int32)
In [18]: arr['x']['a']
Out[18]: array([ 1., 3.])
numpy.lib.recfunctions
一般都需要创建一个新数组以便对dtype进行修改。
跟Python内置的列表一样,ndarray的sort实例方法也是就地排序。
但是,numpy.sort
会为原数组创建一个已排序副本。
两个排序方法(np.sort(arr)
and arr.sort()
)都可以接受一个axis参数,以便沿指定轴向对各块数据进行单独排序。
arr.argsort() and numpy.lexsort()
: 索引值说明了数据在新顺序下的位置。
注: Series和DataFrame的sort_index以及Series的order方法就是通过这些函数的变体实现的。
mergesort是稳定排序,会保持定价元素的相对位置。
numpy.searchsorted
在有序数组中查找元素返回插入位置,保持数组有序。
In [21]: arr = np.array([0,1,4,7,9,24,64])
In [22]: arr.searchsorted(8)
Out[22]: 4
In [23]: arr.searchsorted([0,8,11,16])
Out[23]: array([0, 4, 5, 5])
用边界数组拆分数据数组
In [24]: from pandas import Series
In [25]: data = np.floor(np.random.uniform(0,10000,size=50))
In [26]: bins = np.array([0,100,1000,5000,10000])
In [27]: data
Out[27]:
array([ 8795., 3572., 8139., 8369., 6866., 4000., 4320., 185.,
7171., 7183., 7554., 2747., 8301., 508., 6789., 5572.,
4647., 1800., 6617., 7725., 8510., 6242., 3087., 9541.,
4456., 9974., 7493., 4238., 6600., 2291., 5139., 5193.,
5226., 6799., 1689., 3912., 5704., 7168., 8418., 9963.,
2454., 7647., 718., 5830., 6241., 6469., 3005., 7537.,
6170., 4417.])
In [28]: lables = bins.searchsorted(data)
In [29]: lables
Out[29]:
array([4, 3, 4, 4, 4, 3, 3, 2, 4, 4, 4, 3, 4, 2, 4, 4, 3, 3, 4, 4, 4, 4, 3,
4, 3, 4, 4, 3, 4, 3, 4, 4, 4, 4, 3, 3, 4, 4, 4, 4, 3, 4, 2, 4, 4, 4,
3, 4, 4, 3])
In [30]: np.digitize(data, bins)
Out[30]:
array([4, 3, 4, 4, 4, 3, 3, 2, 4, 4, 4, 3, 4, 2, 4, 4, 3, 3, 4, 4, 4, 4, 3,
4, 3, 4, 4, 3, 4, 3, 4, 4, 4, 4, 3, 3, 4, 4, 4, 4, 3, 4, 2, 4, 4, 4,
3, 4, 4, 3])
In [31]: Series(data).groupby(lables).mean()
Out[31]:
2 470.333333
3 3375.666667
4 7217.031250
dtype: float64
参考《Python for Data Analysis》