1、生成随机数
import numpy as np
data = np.random.randn(2, 3)
data
array([[-0.06180816, -0.34319508, 0.28056151],
[-0.15430366, -0.7140969 , -1.67410168]])
1.1 给随机数加上一个
data*10
array([[ -0.61808156, -3.43195079, 2.80561508],
[ -1.54303661, -7.14096897, -16.74101682]])
data + data
array([[-0.12361631, -0.68639016, 0.56112302],
[-0.30860732, -1.42819379, -3.34820336]])
2、基本属性
一个ndarray是一个通用的多维同类数据容器,也就是说,它包含的每一个元素均为相同类型。每一个数组都有一个shape属性,用来表征数组每一维度的数量;每一个数组都有一个dtype属性,用来描述数组的数据类型。
data.shape
(2, 3)
data.dtype
dtype('float64')
3、生成ndarray
生成数组最简单的方式就是使用array函数。array函数接收任意的序列型对象(当然也包括其他的数组),生成一个新的包含传递数据的NumPy数组。
data1 = [6, 7.5, 8, 1, 1, 100]
arr1 = np.array(data1)
arr1
array([ 6. , 7.5, 8. , 1. , 1. , 100. ])
嵌套序列,例如同等长度的列表,将会自动转换成多维数组:
Out[10]: array([ 6. , 7.5, 8. , 1. , 1. , 100. ])
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 = np.array(data2)
arr2
Out[13]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
因为data2是一个包含列表的列表,所以Numpy数组arr2形成了二维数组。我们可以通过检查ndim和shape属性来确认这一点:
arr2.ndim
Out[14]: 2
arr2.shape
Out[15]: (2, 4)
除非显式地指定,否则np.array会自动推断生成数组的数据类型。数据类型被存储在一个特殊的元数据dtype中。例如,之前的两个例子
arr1.dtype
Out[16]: dtype('float64')
arr2.dtype
Out[17]: dtype('int64')
除了np.array,还有很多其他函数可以创建新数组。例如,给定长度及形状后,zeros可以一次性创造全0数组,ones可以一次性创造全1数组。empty则可以创建一个没有初始化数值的数组。想要创建高维数组,则需要为shape传递一个元组:
np.zeros(5)
Out[20]: array([0., 0., 0., 0., 0.])
np.zeros((2, 3))
Out[21]:
array([[0., 0., 0.],
[0., 0., 0.]])
np.empty((2, 2, 3))
Out[22]:
array([[[-2.31584178e+077, -2.31584178e+077, 3.45845952e-323],
[ 0.00000000e+000, 0.00000000e+000, 6.82116729e-043]],
[[ 6.19533817e-091, 3.53727177e-057, 4.31763870e-038],
[ 2.98832816e-032, 3.99910963e+252, 1.46030983e-319]]])
arange是Python内建函数range的数组版:
np.arange(15)
Out[24]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
4、ndarray的数据类型
数据类型,即dytpe,是一个特殊的对象,它包含了ndarray需要为某一种类型数据所申明的内存块信息(也称为元数据,即表示数据的数据):
arr1 = np.array([1], dtype=np.float32)
arr2 = np.array([1], dtype=np.int32)
arr1
Out[27]: array([1.], dtype=float32)
arr2
Out[28]: array([1], dtype=int32)
5、显式指定数据类型
arr = np.array([1])
arr.dtype
Out[31]: dtype('int64')
arr_float = arr.astype(np.float32)
arr_float.dtype
Out[33]: dtype('float32')
在上面例子中,整数被转换成了浮点数。如果我把浮点数转换成整数,则小数点后的部分将被消除:
arr = np.array([5.6, -10.2])
arr
Out[48]: array([ 5.6, -10.2])
arr.astype(np.int32)
Out[49]: array([ 5, -10], dtype=int32)
如果你有一个数组,里面的元素都是表达数字含义的字符串,也可以通过astype将字符串转换为数字:
arr = np.array(['15.26', '-10.25'], dtype=np.string_)
arr
Out[51]: array([b'15.26', b'-10.25'], dtype='|S6')
arr.astype(np.float32)
Out[52]: array([ 15.26, -10.25], dtype=float32)
6、同形数组计算
对应位置元素做计算:
arr = np.array([[1,2],[3,4]])
arr + arr
Out[54]:
array([[2, 4],
[6, 8]])
arr * arr
Out[55]:
array([[ 1, 4],
[ 9, 16]])
同尺寸数组之间的比较,会比较对应位置的值产生布尔值:
arr == arr
Out[58]:
array([[ True, True],
[ True, True]])
7、数组和标量做计算
带有标量计算的算术操作,会把计算参数传递给数组的每一个元素:
1 / arr
Out[56]:
array([[1. , 0.5 ],
[0.33333333, 0.25 ]])
arr ** 2
Out[57]:
array([[ 1, 4],
[ 9, 16]])
8、一维数组切片,赋值
注意:赋值时会将标量赋值给数组中的每个元素。
arr = np.arange(8)
arr
Out[60]: array([0, 1, 2, 3, 4, 5, 6, 7])
arr[5]
Out[61]: 5
arr[5:8]
Out[62]: array([5, 6, 7])
arr[5:8] = 20
arr
Out[64]: array([ 0, 1, 2, 3, 4, 20, 20, 20])
8.1、切片的引用改变,会体现在原数组中
sub_arr = arr[5:8]
sub_arr[0] = 8240
arr
Out[67]: array([ 0, 1, 2, 3, 4, 8240, 20, 20])
8.2、不写切片值会引用数组中的所有值
arr[:]
Out[68]: array([ 0, 1, 2, 3, 4, 8240, 20, 20])
8.3、显式复制数组切片,而不是引用
切片的改变不会影响到原数组
copy_arr = arr[5:8].copy()
copy_arr[1] = 9345
copy_arr
Out[71]: array([8240, 9345, 20])
arr
Out[72]: array([ 0, 1, 2, 3, 4, 8240, 20, 20])
9 高维数组切片
arr2d = np.array([[1,2],[5,5],[9,8]])
arr2d[2]
Out[74]: array([9, 8])
arr2d[2][1]
Out[76]: 8
在多维数组中,你可以省略后续索引值,返回的对象将是降低一个维度的数组。因此在一个2×2×3的数组arr3d中:
arr3d = np.array([[[1,2,3,4],[5,6,7,8],[1,1,1,1]], [[2,2,2,2],[3,3,3,3],[9,9,9,9]]])
arr3d
Out[78]:
array([[[1, 2, 3, 4],
[5, 6, 7, 8],
[1, 1, 1, 1]],
[[2, 2, 2, 2],
[3, 3, 3, 3],
[9, 9, 9, 9]]])
arr3d[0]
Out[79]:
array([[1, 2, 3, 4],
[5, 6, 7, 8],
[1, 1, 1, 1]])
待续。。。