numpy学习笔记(其二)

ndarray的数据类型

dtype(数据类型)是一个特殊的对象,它含有ndarray将一块内存解释为特定数据类型所需的信息

a = np.array([1,2,3],dtype=np.float64)
a
array([1., 2., 3.])
a.dtype
dtype('float64')
b = np.array([1,2,3],dtype=np.int32)
b
array([1, 2, 3])
b.dtype
dtype('int32')

numpy的数据类型

类型类型代码说明
int8、uint8i1、u1有符号和无符号的8位(1个字节)整形
int16、uint16i2、u2有符号和无符号的16位(2个字节)整形
int32、uint32i3、u3有符号和无符号的32位(4个字节)整形
int64、uint64i4、u4有符号和无符号的64位(8个字节)整形
float16f2半精度浮点数
float32f4或f标准的双精度浮点数。与C的float兼容
float64f8或d标准的双精度浮点数。与C的double和python的float对象兼容
float128f16或g扩展精度浮点数
complex64 、complex128c8、c16分别用两个32位、64位或128位位浮点数表示的复数
complex256c32复数
bool存储True和False值得布尔类型
objectOPython对象类型
string_S固定长度的字符串类型(每个字符一个字节)。例如,要创建一个长度为10的字符串,应使用510
unicode_U固定长度的unicode类型(字节数由平台决定)。跟字符串的定义方式一样(如U10)

可以通过ndarray的astype方法显式的转换其dtype:

#整形转浮点型
a = np.array([1,2,3])
a.dtype
dtype('int32')
a_float = a.astype(np.float64)
a_float.dtype
dtype('float64')
#浮点型转整形,小数点后的数字直接舍去
b = np.array([1.2,2.3,3.4])
b.dtype
dtype('float64')
b_int = b.astype(np.int64)
b_int.dtype
dtype('int64')
b_int
array([1, 2, 3], dtype=int64)
#字符串数组全是数字,也可以转为对应的数值形式
c = np.array(['1.2','2.3','3.4'],dtype=np.string_)
c.dtype
dtype('S3')
c.astype(float)
array([1.2, 2.3, 3.4])
#dtype的另一种用法
a = np.array([1,2,3],dtype=np.int64)
b = np.array([1.1,2.2,3.3],dtype=np.float64)
a.astype(b.dtype)
array([1., 2., 3.])
#dtype的简介表示
empty_uint32 = np.empty(8,dtype='u4')
empty_uint32
array([         0,    5177428,        424,          0, 3538688192,
              482,      65793,          0], dtype=uint32)

数组和标量之间的运算

数组可以使你不用编写循环即可对数据执行批量运算。这通常就叫做矢量化。大小相等的数组之间的任何算术运算都会将运算应用用到元素级。

a = np.array([[1,2,3],[4,5,6]])
a
array([[1, 2, 3],
       [4, 5, 6]])
a * a
array([[ 1,  4,  9],
       [16, 25, 36]])
a - a
array([[0, 0, 0],
       [0, 0, 0]])
1 / a
array([[1.        , 0.5       , 0.33333333],
       [0.25      , 0.2       , 0.16666667]])
a ** 0.5
array([[1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974]])

基本的索引和切片

一维数组和python列表的功能差不多

a = np.arange(5)
a
array([0,1,2,3,4])
a[3]
3
a[1:3]
array([1, 2])
a[1:3]=15
a
array([ 0, 15, 15,  3,  4])

当把一个标量赋值给一个切片时,该值会自动覆盖原先数组。数组切片是原始数组的视图,视图上的任何修改都会直接反应到原数组上。

 a_slice = a[1:3]
In[5]: a_slice[1] = 123456
In[6]: a
Out[6]: array([     0,      1, 123456,      3,      4])
In[7]: a_slice[:] = 64
In[8]: a
Out[8]: array([ 0, 64, 64,  3,  4])

二维数组

In[9]: a2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
In[10]: a2[2]
Out[10]: array([7, 8, 9])
`In[11]: a2[0][2]
Out[11]: 3
In[12]: a2[0,2]
Out[12]: 3

二维数组的索引如下表示
在这里插入图片描述

#三维数组
In[3]: a3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
In[4]: a3
Out[4]: 
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
In[5]: a3[0]
Out[5]: 
array([[1, 2, 3],
       [4, 5, 6]])
In[6]: old_values = a3[0].copy()
In[8]: a3[0] = 42
In[9]: a3
Out[9]: 
array([[[42, 42, 42],
        [42, 42, 42]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
In[10]: a3[0] = old_values
In[11]: a3
Out[11]: 
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
 In[12]: a3[1,0]
Out[12]: array([7, 8, 9])

切片索引

#一维数组
In[13]: a1 = np.arange(10)
In[14]: a1
Out[14]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In[15]: a1[1:6]
Out[15]: array([1, 2, 3, 4, 5])
#二维数组
In[16]: a2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
In[17]: a2
Out[17]: 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
In[18]: a2[:2]
Out[18]: 
array([[1, 2, 3],
       [4, 5, 6]])
 

通过以上例子可以看出,它是沿着第0轴(即第一个中括号)切片的,即切片是沿着一个轴向选取元素的。

In[19]: a2[:2,1:]
Out[19]: 
array([[2, 3],
       [5, 6]])
 In[20]: a2[1,:2]
Out[20]: array([4, 5])
In[21]: a2[2,:1]
Out[21]: array([7])
In[22]: a2[:,:1]
Out[22]: 
array([[1],
       [4],
       [7]])
 In[24]: a2[:2,1:] = 0
In[25]: a2
Out[25]: 
array([[1, 0, 0],
       [4, 0, 0],
       [7, 8, 9]])

布尔值索引
假设一个用于存储数据的数组以及一个存储姓名的数组(含有重复项)。使用numpy.random中的randn函数生成一些正态分布的随机数据

In[29]: names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
In[30]: names
Out[30]: array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='<U4')
In[31]: data = np.random.randn(7,4)
In[32]: data
Out[32]: 
array([[ 1.06804939,  0.53763406, -0.34468005, -0.26877366],
       [-0.77521385, -1.22275166, -0.40538837, -0.55845101],
       [-1.38442773, -1.45071359,  0.5586666 ,  0.07969325],
       [-0.16880411, -0.3988792 , -1.28797105,  0.62871321],
       [ 1.15519442, -0.40048694,  1.53369361,  0.70366078],
       [ 0.51046507, -1.04062609, -1.3817315 ,  0.87470915],
       [-0.58902799, -0.69330514,  0.49844266, -0.05298475]])

假设每个名字都对应data数组的一行

In[33]: names == "Bob"
Out[33]: array([ True, False, False,  True, False, False, False])
In[34]: data[names == 'Bob']
Out[34]: 
array([[ 1.06804939,  0.53763406, -0.34468005, -0.26877366],
       [-0.16880411, -0.3988792 , -1.28797105,  0.62871321]])
In[35]: data[names == 'Bob',2:]
Out[35]: 
array([[-0.34468005, -0.26877366],
       [-1.28797105,  0.62871321]])
In[36]: data[names == 'Bob',3]
Out[36]: array([-0.26877366,  0.62871321])

选择‘Bob’以外的值可以用不等符号(!=),也可以直接通过非(~)。

In[37]: names != 'Bob'
Out[37]: array([False,  True,  True, False,  True,  True,  True])
In[40]: data[~(names == 'Bob')]
Out[40]: 
array([[-0.77521385, -1.22275166, -0.40538837, -0.55845101],
       [-1.38442773, -1.45071359,  0.5586666 ,  0.07969325],
       [ 1.15519442, -0.40048694,  1.53369361,  0.70366078],
       [ 0.51046507, -1.04062609, -1.3817315 ,  0.87470915],
       [-0.58902799, -0.69330514,  0.49844266, -0.05298475]])

同时选取多个名字的组合需要使用|(或)

In[45]: mask = (names == 'Bob') | (names == 'Will')
In[46]: mask
Out[46]: array([ True, False,  True,  True,  True, False, False])
In[47]: data[mask]
Out[47]: 
array([[ 1.06804939,  0.53763406, -0.34468005, -0.26877366],
       [-1.38442773, -1.45071359,  0.5586666 ,  0.07969325],
       [-0.16880411, -0.3988792 , -1.28797105,  0.62871321],
       [ 1.15519442, -0.40048694,  1.53369361,  0.70366078]])

通过布尔型数组设置值

In[54]: data[data < 0] = 0
In[55]: data
Out[55]: 
array([[1.06804939, 0.53763406, 0.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        ],
       [0.        , 0.        , 0.5586666 , 0.07969325],
       [0.        , 0.        , 0.        , 0.62871321],
       [1.15519442, 0.        , 1.53369361, 0.70366078],
       [0.51046507, 0.        , 0.        , 0.87470915],
       [0.        , 0.        , 0.49844266, 0.        ]])

In[57]: data[names != 'Joe'] = 7
In[58]: data
Out[58]: 
array([[7.        , 7.        , 7.        , 7.        ],
       [0.        , 0.        , 0.        , 0.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [0.51046507, 0.        , 0.        , 0.87470915],
       [0.        , 0.        , 0.49844266, 0.        ]])

花式索引
花式索引即利用整数数组进行索引。

In[59]: arr = np.empty((8,4))
In[60]: arr
Out[60]: 
array([[6.91409243e-310, 2.20472012e-316, 6.91409302e-310,
        6.91409301e-310],
       [6.91408939e-310, 6.91409300e-310, 6.91409297e-310,
        6.91409301e-310],
       [6.91409175e-310, 6.91408937e-310, 6.91409302e-310,
        6.91409302e-310],
       [6.91409302e-310, 6.91409301e-310, 6.91409300e-310,
        6.91409302e-310],
       [6.91409300e-310, 6.91409302e-310, 6.91409300e-310,
        6.91409193e-310],
       [6.91409195e-310, 6.91409302e-310, 6.91409174e-310,
        6.91409299e-310],
       [6.91409298e-310, 6.91409295e-310, 6.91409301e-310,
        6.91409011e-310],
       [6.91408640e-310, 6.91409302e-310, 6.91409190e-310,
        6.91409300e-310]])
In[61]: for i in range(8):
   ...:     arr[i] = i
   ...:     
In[62]: arr
Out[62]: 
array([[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.]])

为了以特定顺序选取行子集,只需要传入一个用于指定顺序的整数列表或者ndarray即可。

In[63]: arr[[1,2,3,4]]
Out[63]: 
array([[1., 1., 1., 1.],
       [2., 2., 2., 2.],
       [3., 3., 3., 3.],
       [4., 4., 4., 4.]])

使用负数将从末尾开始选取行

In[64]: arr[[-1,-2,-3]]
Out[64]: 
array([[7., 7., 7., 7.],
       [6., 6., 6., 6.],
       [5., 5., 5., 5.]])

一次传入多个索引数组会有一点特别。他返回的是一个一维数组,其中的元素对应各个索引元组

In[67]: arr = np.arange(32).reshape((8,4))#reshape用于重构多维数组形状
In[68]: arr
Out[68]: 
array([[ 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]])
In[70]: arr[[0,1,2,3],[0,1,2,3]]
Out[70]: array([ 0,  5, 10, 15])
 

为了得到矩阵区域形式的矩阵的行列子集

In[71]: arr[[0,1,2,3]][:,[0,1,2,3]]
Out[71]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
In[72]: arr[np.ix_([0,1,2,3],[0,1,2,3])]
Out[72]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

花式索引和切片不一样,它总是将数据复制到新数组中。

数组转置和轴对换
转置是重塑的一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作)。数组不仅有transpose方法,还有一个特殊的T属性。

In[76]: arr = np.arange(15).reshape((3,5))
In[77]: arr
Out[77]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
In[78]: arr.T
Out[78]: 
array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])

在进行矩阵计算时,经常需要,比如利用numpy.dot计算矩阵内积X**T * X

n[79]: arr = np.random.randn(6,3)
In[80]: arr
Out[80]: 
array([[-1.07635721, -2.07780713, -0.04095446],
       [ 0.08187961, -1.02451744, -0.31626861],
       [ 1.2343947 , -0.04506441, -0.75610648],
       [-1.69744337,  0.12104636, -0.60267598],
       [-0.38439969, -0.5898125 , -0.82001761],
       [ 1.09967225,  2.18918989, -0.48352121]])
In[81]: np.dot(arr.T,arr)
Out[81]: 
array([[ 6.92733555,  4.52559412, -0.10864014],
       [ 4.52559412, 10.52403267, -0.20462317],
       [-0.10864014, -0.20462317,  1.9428401 ]])

对于高维数组,转置需要得到一个由轴编号组成的元组才能对这些轴进行转置。

In[96]: arr = np.arange(16).reshape((2,2,4))
In[97]: arr
Out[97]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])
In[98]: arr.transpose((1,0,2))
Out[98]: 
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])
shapeindex
20
21
42

transpose的参数即是index的元组,同时也是arr中每一个元素的索引,arr中的元素位置随着参数的改变而改变。
多维数组的swapaxes方法。

In[99]: arr.swapaxes(1,2)
Out[99]: 
array([[[ 0,  4],
        [ 1,  5],
        [ 2,  6],
        [ 3,  7]],

       [[ 8, 12],
        [ 9, 13],
        [10, 14],
        [11, 15]]])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值