NumPy的ndarray:一种多维数组对象
1.创建ndarray
data1=[6,7.5,8,0,1]
arr1=np.array(data1)
print arr1
结果为:
[ 6. 7.5 8. 0. 1. ]
data2=[[1,2,3,4],[5,6,7,8]]
arr2=np.array(data2)
print arr2
结果为:
[[1 2 3 4]
[5 6 7 8]]
除了np.array外,还有一些函数也可以新建数组。比如,zeros和ones分别可以创建指定长度或形状的全0或全1数组。empty也可以创建一个没有任何具体值的数组。
print zeros(10)
结果为:
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
print np.ones((2,4))
结果为:
[[ 1. 1. 1. 1.]
[ 1. 1. 1. 1.]]
2.ndarray的数据类型
arr3=np.array([1,2,3],dtype=np.float64)
arr4=np.array([1,2,3],dtype=np.int32)
print arr3.dtype
print arr4.dtype
结果为:
float64
int32
可以通过astype方法显示地转换其type
arr5=np.array([1,2,3,4,5])
print arr5.dtype
float_arr=arr5.astype(np.float64)
print float_arr.dtype
结果为:
int32
float64
数组的dtype还有另外一个用法:
int_array=np.arange(10)
calibers=np.array([1,343,23],dtype=np.float64)
print int_array.astype(calibers.dtype)
结果为:
[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
3.数组与标量间的运算
arr6=np.array([[1,2,3],[4,5,6]])
print arr6*arr6
结果为:
[[ 1 4 9]
[16 25 36]]
4.基本的索引和切片
跟列表最重要的区别在于,数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。
arr7=np.arange(10)
arr_slice=arr7[5:8]
arr_slice[1]=123
print arr7
结果为:
[ 0 1 2 3 4 5 123 7 8 9]
备注:如果你想得到的是ndarray切片的一份副本而非视图,则需要显式的进行复制操作,例如arr[5:8].copy()
在一个二维数组中,各索引位置上的元素不再是标量而是一维数组
arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]])
print arr2d[2]
结果为:
[7 8 9]
可以对各个元素进行递归访问,也可以传入一个以逗号隔开的索引列表来选取单个元素
arr2d[2][0]
arr2d[2,0]
5.切片索引
对于高纬度对象,你可以在一个或多个轴上进行切片,也可以跟整数索引混合使用。
arr2d1=np.array([[1,2,3],[4,5,6],[7,8,9]])
print arr2d1[:2]
print arr2d1[:2,1:]
结果为:
[[1 2 3]
[4 5 6]]
[[2 3]
[5 6]]
像arr2d1[:2,1:]这么的切片只能得到相同维数的数组视图。
通过将整数索引和切片混合,可以得到低纬度的切片:
6.布尔型索引
names=np.array(['zhuheng','benben','xiaoyang','benben','xiaoyang','heng','xiaoyang'])
data=np.random.randn(7,4)
print data
print names=='zhuheng'
print data[names=='zhuheng']
print data[names=='benben',:2]
#要选择除“zhuheng”以外的值,可以使用!=或者负号(-)
print data[-(names=='zhuheng')]
结果为:
[[ 0.40184471 0.49439702 -0.96375705 0.4830126 ]
[-0.60149309 -1.11686142 1.29860408 -1.49726835]
[-0.1495726 -2.28302963 1.00246332 0.70656737]
[-1.45434958 1.2701399 -0.68081126 -0.16684455]
[ 0.84037574 -0.1155909 1.16563124 -0.06460655]
[-0.75422254 0.05167235 0.13808055 0.79250884]
[ 0.05079752 0.34693844 0.49624642 -0.44551127]]
[ True False False False False False False]
[[ 0.40184471 0.49439702 -0.96375705 0.4830126 ]]
[[-0.60149309 -1.11686142]
[-1.45434958 1.2701399 ]]
[[-0.60149309 -1.11686142 1.29860408 -1.49726835]
[-0.1495726 -2.28302963 1.00246332 0.70656737]
[-1.45434958 1.2701399 -0.68081126 -0.16684455]
[ 0.84037574 -0.1155909 1.16563124 -0.06460655]
[-0.75422254 0.05167235 0.13808055 0.79250884]
[ 0.05079752 0.34693844 0.49624642 -0.44551127]]
使用&、|之类的布尔算术符可以组合使用,如:
mask=(names=='zhuheng') | (names='benben')
为了将data中的所有负值都设置为0,我们只需要:data[data<0]=0
7.花式索引
利用整数数组进行索引
arr7=np.empty((8,4))
for i in range(8):
arr7[i]=i
print arr7
#为了以特定顺序选择行子集,只需传入一个用户指定顺序的整数列表或ndarray即可
print arr7[[4,3,0,6]]
#使用负数索引将会从末尾开始选取行
print arr7[[-3,-5,-7]]
print '---------------------------------------------------------'
arr8=np.arange(32).reshape((8,4))
print arr8
print arr8[[1,5,7,2],[0,3,1,2]]
print arr8[[1,5,7,2]][:,[0,3,1,2]]
#np.ix_实现的结果与上面的一样
print arr8[np.ix_([1,5,7,2],[0,3,1,2])]
结果为:
[[ 0. 0. 0. 0.]
[ 1. 1. 1. 1.]
[ 2. 2. 2. 2.]
[ 3. 3. 3. 3.]
[ 4. 4. 4. 4.]
[ 5. 5. 5. 5.]
[ 6. 6. 6. 6.]
[ 7. 7. 7. 7.]]
[[ 4. 4. 4. 4.]
[ 3. 3. 3. 3.]
[ 0. 0. 0. 0.]
[ 6. 6. 6. 6.]]
[[ 5. 5. 5. 5.]
[ 3. 3. 3. 3.]
[ 1. 1. 1. 1.]]
---------------------------------------------------------
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]
[24 25 26 27]
[28 29 30 31]]
[ 4 23 29 10]
[[ 4 7 5 6]
[20 23 21 22]
[28 31 29 30]
[ 8 11 9 10]]
[[ 4 7 5 6]
[20 23 21 22]
[28 31 29 30]
[ 8 11 9 10]]
数组转置和轴对换
转置是重塑的一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作);不仅有transpose方法,还有一个特殊的T属性:
arr9=np.arange(15).reshape((3,5))
print arr9
print arr9.T
print '---------------------------------------------------------'
#在进行矩阵计算时,经常用到该操作,比如利用np.dot计算矩阵内积
arr10=np.random.rand(6,3)
print arr10
print np.dot(arr10.T,arr10)
结果为:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
---------------------------------------------------------
[[ 0.18474531 0.80872726 0.9166154 ]
[ 0.69298463 0.33925467 0.19984274]
[ 0.06745926 0.89110092 0.88223502]
[ 0.61478731 0.99753697 0.23356604]
[ 0.78283627 0.13917963 0.59375074]
[ 0.12775166 0.14528319 0.72813074]]
[[ 1.52602582 1.18540795 1.06876622]
[ 1.18540795 2.59875256 2.01666381]
[ 1.06876622 2.01666381 2.59572694]]
对于高维数组,transpose需要得到一个由轴编号组成的元组才能对这些轴进行转置
arr11=np.arange(16).reshape((2,2,4))
print arr11
print arr11.transpose((1,0,2))
结果为:
[[[ 0 1 2 3]
[ 4 5 6 7]]
[[ 8 9 10 11]
[12 13 14 15]]]
[[[ 0 1 2 3]
[ 8 9 10 11]]
[[ 4 5 6 7]
[12 13 14 15]]]
简单的转置可以使用.T,ndarray还有一个swapaxes方法,它需要接受一对轴编号
arr12=np.arange(16).reshape((2,2,4))
print arr12
print arr12.swapaxes(1,2)
结果为:
[[[ 0 1 2 3]
[ 4 5 6 7]]
[[ 8 9 10 11]
[12 13 14 15]]]
[[[ 0 4]
[ 1 5]
[ 2 6]
[ 3 7]]
[[ 8 12]
[ 9 13]
[10 14]
[11 15]]]
通用函数:快速的元素级数组函数
arr13=np.arange(12)print np.sqrt(arr13)
print np.exp(arr13)
结果为:
[ 0. 1. 1.41421356 1.73205081 2. 2.23606798
2.44948974 2.64575131 2.82842712 3. 3.16227766 3.31662479]
[ 1.00000000e+00 2.71828183e+00 7.38905610e+00 2.00855369e+01
5.45981500e+01 1.48413159e+02 4.03428793e+02 1.09663316e+03
2.98095799e+03 8.10308393e+03 2.20264658e+04 5.98741417e+04]
刚刚都是一元的,另外一些接受2个数组,并返回一个结果数组
x=np.random.rand(8)
y=np.random.rand(8)
print x
print y
print np.maximum(x,y)
结果为:
[ 0.48390421 0.8133998 0.59285289 0.64019556 0.55984221 0.71040303
0.16971892 0.6755642 ]
[ 0.68422203 0.60642309 0.70733461 0.98306697 0.01549487 0.69491535
0.32657672 0.39511961]
[ 0.68422203 0.8133998 0.70733461 0.98306697 0.55984221 0.71040303
0.32657672 0.6755642 ]
modf可以用于返回浮点数数组的小数和整数部分
arr14=np.random.rand(7)*5
print arr14
print np.modf(arr14)
结果为:
[ 3.0077387 0.57159816 1.75993908 2.31184667 0.72279949 1.35632123
3.06273501]
(array([ 0.0077387 , 0.57159816, 0.75993908, 0.31184667, 0.72279949,
0.35632123, 0.06273501]), array([ 3., 0., 1., 2., 0., 1., 3.]))