numpy基础操作(一)

一、生成ndarray

1. 最简单的方法就是使用array函数。array函数接收任何的序列型对象(当然也包括其他的数组),生成一个新的包含传递数组的numpy数组。例如:
import numpy as np
data1 = [6, 7.5,  8,  0, 1]
arr1 = np.array(data1)
arr1
array([ 6. ,  7.5,  8. ,  0. ,  1. ])
2.嵌套序列,例如同等长度的列表,将会自动转换成多维数组
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 = np.array(data2)
arr2
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

通过ndim和shape可以查看属性:

arr2.ndim
2
arr2.shape
(2, 4)
3. 除了用np.array,还有很多其他的函数可以创建新数组。

例如,给定长度和形状后,zeros可以一次性创建全为0的数组,ones可以创建全为1的数组。empty可以创建一个没有初始化数组的数组。想要创建高维数组,则需要为shape传递一个元组:

np.zeros(10)
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
np.zeros((3, 6))
array([[ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.]])
np.empty((2, 3, 2))
array([[[  6.93191462e-310,   1.59160125e-316],
        [  0.00000000e+000,   0.00000000e+000],
        [  0.00000000e+000,   5.68519743e-062]],

       [[  3.59789606e+179,   6.52172099e-038],
        [  1.41915235e+161,   4.42531362e-062],
        [  1.46169329e+185,   7.13064093e-067]]])

想要用np.empty创建一个全为0的数组并不安全,有些时候它可能返回未初始化的垃圾数值

arange是python内建函数range的数组版:

np.arange(15)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

下表是标准数组的生成函数,如果没有特别声明。默认的数据类型都是float64

函数名描述
array将输入数据转换为ndarray,如不显式致命数据类型,将自动推断
asarray将输入转为ndarray,如果已经是ndarray则不再复制
arangepython内建函数range的数组版,返回一个数组
ones根据形状生成一个全1的数组
ones_like根据所给的数组生成一个形状一样的全1数组
zeros根据形状生成一个全0的数组
zeros_like根据所给的数组生成一个形状一样的全0数组
empty根据形状生成一个没有初始化数值的空数组
empty_like根据所给的数组生成一个形状一样但没有初始化数据的空数组
full根据形状生成一个制定数值的数组
full_like根据所给的数组生成一个形状一样但内容是指定数值的数组
eye,identity生成一个 N ⋅ N N\cdot N NN的单位矩阵

二、ndarray的数据类型

numpy数据类型如下表所示:

类型类型代码
int8,uint8i1,u1
int16,uint16i2,u2
int32,uint32i4,u4
int64,uint64i8,u8
float16f2
float32f4或f
float64f8或d
float128f16或g
complex64c8
complex128c16
complex256c32
bool?
objecto
string_S
unicode_U

你可以使用astype方法显式地转换数组的数据类型

arr = np.array([1, 2, 3, 4, 5])
arr.dtype
dtype('int64')
float_arr = arr.astype(np.float64)
float_arr.dtype
dtype('float64')

在上面例子中,整数被转换成了浮点数,如果我把浮点数转换成整数,则小数点后的部分将被消除

arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
arr.dtype
dtype('float64')
arr.astype(np.int32)
array([ 3, -1, -2,  0, 12, 10], dtype=int32)

三、基础索引与切片

一位数组比较简单,看起来和python的列表很类似:

arr = np.arange(10)
arr[5]
5
arr[5:8]
array([5, 6, 7])
arr[5:8] = 12
arr
array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])

如你所见,如果你传入了一个数值给数组的切片,数值被传递给了整个切片,区别于python的内建列表,数组的切片是原数组的视图。这意味着数据并不是被复制了,任何对于视图的修改都会放映到原数组上。

arr_slice = arr[5:8]
arr_slice
array([12, 12, 12])

当我改变arr_slice,变化也会体现在原数组上:

arr_slice[1] = 12345
arr
array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,     9])

如果你想要一份数组切片的拷贝而不是一份视图的化话,你就逆序显式地复制这个数组,例如arr[5:8].copy
对于更高唯独的数组,你会有更多选择。在一个二维数组中,每个索引值对应的元素不再是一个值,而是一个数组:

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2]
array([7, 8, 9])
arr2d[0][2]
3
arr2d[0, 2]
3
arr2d[:2, 1:]
array([[2, 3],
       [5, 6]])
arr2d[2]
array([7, 8, 9])
arr2d[:, :2]
array([[1, 2],
       [4, 5],
       [7, 8]])

arr2d[1, :2]和arr2d[1:2, :2]有所不同

arr2d[1, :2] # shape = (2, )
array([4, 5])
arr2d[1:2, :2] # shape = (1, 2)
array([[4, 5]])

四、布尔索引

让我们考虑以下例子,假设我们的数据都在数组中,并且数组中的数据是一些存在重复的人名。我会使用numpy.random中的randn函数来生成一些随机正态分布的数据:

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = np.random.randn(7, 4)
names
array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'],
      dtype='<U4')
data
array([[-0.70522835,  1.47087563,  0.35250176,  0.02848163],
       [-0.78749969, -0.72789731, -0.7797904 ,  0.77486765],
       [ 1.30127429,  0.62887439,  1.06599137,  1.52760906],
       [ 0.9931709 ,  0.96859579,  0.89749706,  0.09828308],
       [ 1.46165639,  0.42842885,  0.24971774,  0.26540473],
       [-1.34049878,  0.39110936, -1.40111365,  0.6045064 ],
       [ 0.30309953,  1.29267219,  0.66753705, -0.86407424]])

假设每个人名都和data数组中的一行相对应,并且我们想要选中所有的‘Bob’对应的行。与数学操作类似,数组的比较操作(比如 == )也是可以向量化的。因此,比较names数组和字符串’Bob’会产生一个布尔值数组:

names == 'Bob'
array([ True, False, False,  True, False, False, False], dtype=bool)
data[names == 'Bob']
array([[-0.70522835,  1.47087563,  0.35250176,  0.02848163],
       [ 0.9931709 ,  0.96859579,  0.89749706,  0.09828308]])

布尔值数组的长度必须和数组轴索引长度一致。你甚至还可以用切片或者整数值(或整数值的序列)对布尔值数组进行混合和匹配。

data[names == 'Bob', 2:]
array([[ 0.35250176,  0.02848163],
       [ 0.89749706,  0.09828308]])

当要选择三个名字中的两个来组合多个布尔值条件时,需要使用布尔算术运算符,如&(and)和|(or):

注意:当使用复合条件时,只能用&和|,不能用and和or

mask = (names == 'Bob') | (names == 'Will')
mask
array([ True, False,  True,  True,  True, False, False], dtype=bool)
mask = (names == 'Bob') or (names == 'Will')
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-58-bae01d3eeda5> in <module>()
----> 1 mask = (names == 'Bob') or (names == 'Will')


ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

基于常识来设置布尔值数组的值也是可行的。将data中所有的负值设置为0,我们需要做:

data[data < 0] = 0
data
array([[ 0.        ,  1.47087563,  0.35250176,  0.02848163],
       [ 0.        ,  0.        ,  0.        ,  0.77486765],
       [ 1.30127429,  0.62887439,  1.06599137,  1.52760906],
       [ 0.9931709 ,  0.96859579,  0.89749706,  0.09828308],
       [ 1.46165639,  0.42842885,  0.24971774,  0.26540473],
       [ 0.        ,  0.39110936,  0.        ,  0.6045064 ],
       [ 0.30309953,  1.29267219,  0.66753705,  0.        ]])

五、神奇索引

假设我们有一个8 × 4的数组:

arr = np.empty((8, 4))
for i in range(8):
    arr[i] = i
arr
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.]])

为了选出一个符合特定顺序的子集,你可以简单地通过传递一个包含指明所需顺序的列表或数组来完成:

arr[[4, 3, 0 ,6]]
array([[ 4.,  4.,  4.,  4.],
       [ 3.,  3.,  3.,  3.],
       [ 0.,  0.,  0.,  0.],
       [ 6.,  6.,  6.,  6.]])
arr[[-3, -5, -7]]
array([[ 5.,  5.,  5.,  5.],
       [ 3.,  3.,  3.,  3.],
       [ 1.,  1.,  1.,  1.]])

传递多个索引数组时情况有些许不同,这样会根据每个索引元组对应的元素选出一个一位数组:

arr = np.arange(32).reshape((8, 4))
arr
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]])
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
array([ 4, 23, 29, 10])

通常情况下,我们所设想的结果是通过选择矩阵中行列的子集所形成的矩形区域。下面是实现我们想法的一种方式:

arr[[1, 5, 7, 2]] [:, [0, 3, 1, 2]]
array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])

注意,神奇索引与切片不同,它总是将数据负值到一个新的数组中

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值