接着之前的文章,这次来了解下numpy的数据类型、基本运算、和切片。
数据类型
dtype(数据类型)是⼀个特殊的对象,它含有ndarray将⼀块内存解释为特定数据类型所需的信息。可以用dtype来查看数组类型、也可以采用astype来进行数据类型转换。
In [33]: arr1 = np.array([1, 2, 3], dtype=np.float64)
In [34]: arr2 = np.array([1, 2, 3], dtype=np.int32)
In [35]: arr1.dtype
Out[35]: dtype('float64')
In [36]: arr2.dtype
Out[36]: dtype('int32')
In [37]: arr = np.array([1, 2, 3, 4, 5])
In [38]: arr.dtype
Out[38]: dtype('int64')
In [39]: float_arr = arr.astype(np.float64)
In [40]: float_arr.dtype
Out[40]: dtype('float64')
注意:
整数被转换成了浮点数。如果将浮点数转换成整数,则⼩数部分将会被截取删除。
其支持的所有数据类型如下表所示:
类型 | 类型代码 | 说明 |
int8,uint8 | i1,u1 | 有符号和无符号的8位(1个字节)整型 |
int16,uint16 | i2,u2 | 有符号和无符号的16位(2个字节)整型 |
int32,uint32 | i4,u4 | 有符号和无符号的32位(4个字节)整型 |
int64,uint64 | i8,u8 | 有符号和无符号的64位(8个字节)整型 |
float16 | f2 | 半精度浮点数 |
float32 | f4或f | 标准的单精度浮点数。与c的float兼容 |
float64 | f8或d | 标准的双精度浮点数。与C的double和Python的float对象兼容。 |
float128 | f16或g | 扩展精度浮点数 |
complex64、complex128、complex256 | c8、c16、c32 | 分别用两个32位,64位或128位浮点数表示的附属 |
object | O | Python对象类型 |
bool | ? | 存储True和False值得布尔类型 |
string_ | S | 固定长度的字符串类型(每个字符1个字节) |
Unicode_ | U | 固定长度的Unicode类型(字节数由平台决定) |
Numpy数组的基本运算
数组很重要,因为它使你不⽤编写循环即可对数据执⾏批量运算。NumPy
⽤户称其为⽮量化(
vectorization
)。⼤⼩相等的数组之间的任何算术运算都会将运算应⽤到元素级:
In [51]: arr = np.array([[1., 2., 3.], [4., 5., 6.]])
In [52]: arr
Out[52]: array([[1., 2., 3.],
[4., 5., 6.]])
In [53]: arr * arr
Out[53]:
array([ 1., 4., 9.],
[ 16., 25. , 36.]])
In [54]: arr - arr
Out[54]:
array([[ 0., 0., 0.],
[ 0., 0., 0.]])
数组与标量的算术运算会将标量值传播到各个元素:
In [55]: 1 / arr
Out[55]:
array([[ 1. , 0.5 , 0.3333],
[ 0.25 , 0.2 , 0.1667]])
In [56]: arr ** 0.5
Out[56]:
array([[ 1. , 1.4142, 1.7321],
[ 2. , 2.2361, 2.4495]])
Numpy基本的切片和索引
numpy的数组索引和切片大致类似与Python列表的功能差不多。
In [60]: arr = np.arange(10)
In [61]: arr
Out[61]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [62]: arr[5]
Out[62]: 5
In [63]: arr[5:8]
Out[63]: array([5, 6, 7])
In [64]: arr[5:8] = 12
In [65]: arr
Out[65]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
#做一个array的切片
In [66]: arr_slice = arr[5:8]
In [67]: arr_slice
Out[67]: array([12, 12, 12])
In [68]: arr_slice[1] = 12345
In [69]: arr
Out[69]: array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
如上代码所示,当你将⼀个标量值赋值给⼀个切⽚时(如 arr[5:8]=12),该值会⾃动传播(也就说后⾯将会讲到的
“
⼴播”
)到整个选区。跟列表最重要的区别在于,数组切⽚是原始数组的视图。当修改其中的值,原数组也会发生变化。
In [72]:arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
In [73]:arr2d[2]
Out[73]: array([7, 8, 9])
In [74]: arr2d[0][2]
Out[74]: 3
In [75]: arr2d[0, 2]
Out[75]: 3
对于⾼维度数组,能做的事情更多。在⼀个⼆维数组中,各索引位置上的元素不再是标量⽽是⼀维数组。因此,可以对各个元素进⾏递归访问,但这样需要做的事情有点多。你也可以传⼊⼀个以逗号隔开的索引列表来选取单个元素。