Numpy基础(1)ndarray多维数组对象

1.多维数组对象

ndarray是一个快读、灵活的大型数据集容器,允许使用类似于标量的操作语法在整块数据上进行数学计算

import numpy as np

# 创建一个简单的numpy数组
data1 = [6.7, 5.5, 2.8, 9.1]
arr1 = np.array(data1)
print(arr1)
# out:
# [6.7 5.5 2.8 9.1]

# 嵌套序列,同等长度的列表,会自动转换成多维函数
data2 = [[1, 2, 3, 4], [6, 8, 9, 0]]
arr2 = np.array(data2)
print(arr2)
# out:
# [[1 2 3 4]
#  [6 8 9 0]]

# 除非显示地指定,否则np.array会自动推断生成数组的数据类型,存储在特殊的元数据dtype中
print(arr1.dtype)
# out: float64

# 还有其他的函数也可以创建新数组
arr3 = np.zeros(10)
arr4 = np.zeros((3, 10))    # 创建3行10列的零数组
arr5 = np.ones(10)
arr6 = np.ones((2, 3))
arr_empty = np.empty((2, 9))    # 生成一个2行9列的空二维数组
arr9 = np.full((2, 2), 10)      # 生成一个2行2列且元素全为10的二维数组

# *-*-*-*-*-*
arr11 = np.eye(10)              # 生成单位矩阵 - 对角线都为1,其余为0
arr12 = np.identity(11)
print(arr11)
print(arr12)

# *-*-*-*-*-*
arr7 = np.ones_like(arr1)       # 生成一个形状和arr1相同的全1数组
arr8 = np.zeros_like(arr1)      # 生成一个形状和arr1相同的全0数组
arr_empty_size = np.empty_like(arr1)
arr10 = np.full_like(arr1, 10)  # 生成一个形状和arr1相同的全为10的数组

# arange() - 类似于range()
print(np.arange(10))
# out:[0 1 2 3 4 5 6 7 8 9]

一个ndarray数组的每个元素都是相同类型,每一个数组都有一个shape属性,用来表征数组每一维度的数量

每一个数组都有一个dtype属性,用来表述数组的数据类型

import numpy as np
data = np.random.randn(2, 3)
print(data.shape)
print(data.dtype)

2.ndarray数组生成函数和数据类型

数组生成函数:https://blog.csdn.net/weixin_37887248/article/details/81779405

常用:array、asarray、arange、eye

数据类型:

bool_ 布尔型数据类型(True 或者 False)
int_ 默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc 与 C 的 int 类型一样,一般是 int32 或 int 64
intp 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8 字节(-128 to 127)
int16 整数(-32768 to 32767)
int32 整数(-2147483648 to 2147483647)
int64 整数(-9223372036854775808 to 9223372036854775807)
uint8 无符号整数(0 to 255)
uint16 无符号整数(0 to 65535)
uint32 无符号整数(0 to 4294967295)
uint64 无符号整数(0 to 18446744073709551615)
float_ float64 类型的简写
float16 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_ complex128 类型的简写,即 128 位复数
complex64 复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128 复数,表示双 64 位浮点数(实数部分和虚数部分)

3.数组算术、基础索引和切片

3.1数组算术

numpy允许对数组进行批量化操作而不是使用for循环,称这种特性为向量化

>>> import numpy as np
>>> arr = np.array([[1, 2, 3], [4, 5, 6]])
>>> arr
array([[1, 2, 3],
       [4, 5, 6]])
>>> arr * arr
array([[ 1,  4,  9],
       [16, 25, 36]])
>>> arr + arr
array([[ 2,  4,  6],
       [ 8, 10, 12]])
>>> arr - arr
array([[0, 0, 0],
       [0, 0, 0]])

带有标量计算的算术操作,会把计算参数传递给数组的每一个元素

>>> 1/arr
array([[1.        , 0.5       , 0.33333333],
       [0.25      , 0.2       , 0.16666667]])
>>> np.sqrt(arr)
array([[1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974]])

两个数组可以进行比较:

>>> arr > arr2
array([[False, False, False],
       [False, False, False]])
>>> arr2 > arr
array([[ True,  True,  True],
       [ True,  True,  True]])

3.2一维数组索引

数组的索引和python中对列表的操作类似

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

所有的数组切片和重新赋值的操作都直接反映在原数组上,因为Numpy被设计成用来处理大量数据,因此执行复制操作有时候是不明智的

举例子:例子中的arr_slice[1]的改变直接会反映在arr1中

>>> arr_slice = arr1[5:8]
>>> arr_slice
array([5, 6, 7])
>>> arr_slice[1] = 100
>>> arr1
array([  0,   1,   2,   3,   4,   5, 100,   7,   8,   9])

如果使用[:]是选中全部元素

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

如果要得到复制的数组,需要使用copy()

>>> arr_copy = arr2[5:8].copy()
>>> arr_copy
array([100, 100, 100])

3.3二维数组以及高维数组索引

索引的方式基本差不多

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

3.4二维数组的切片

索引中逗号前面代表行,后面代表列,然后是各行各列的起点和终点

注意:使用 0:总长 才能完整取到行或列的所有部分(或者直接使用一个冒号 : )

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

4.布尔索引

假设有一个序列是包含许多元素,其中含有相同的元素,要求查看每一个元素是不是所要求的一个元素

假设有一个name序列,可以通过布尔索引来得到一个真值序列

>>> import numpy as np
>>> name = np.array(['a', 'b', 'c', 'd', 'a', 'e', 'f', 'g'])
>>> name == 'a'
array([ True, False, False, False,  True, False, False, False])

甚至还可以在索引数组的时候使用布尔索引,这样就可以将数组中的数据和另一个数组对应起来了

>>> data
array([[ 1.24499916,  1.09219008,  0.54067091, -0.54060987, -0.38934891],
       [ 1.67435833,  1.25077416, -0.2711316 ,  0.92815044,  0.25917165],
       [-0.34178734, -0.32582264, -0.31516525, -0.50118741, -0.4396202 ],
       [-1.00490801, -1.0432731 , -0.08440476,  0.34410518,  0.4288193 ],
       [-0.19588292, -0.44508004,  1.29878205,  0.74319183, -1.21645021],
       [ 0.07012634, -1.48510403, -0.50732563, -0.42672358,  0.85432296],
       [-0.44631006,  0.44129148, -1.97539492, -0.46876121, -0.58529733],
       [ 0.37695035, -0.48498234,  0.61066879,  1.42635512, -0.28060154]])
>>> data[name == 'a']
array([[ 1.24499916,  1.09219008,  0.54067091, -0.54060987, -0.38934891],
       [-0.19588292, -0.44508004,  1.29878205,  0.74319183, -1.21645021]])

注意:最好保证在使用布尔索引对数组进行索引的时候,数组的长度要和布尔索引的数组的长度尽量保证一致

还可以使用其他条件表达式来对条件进行修改:!=、~

当同时满足多个条件的时候,可以使用 &、| 等逻辑操作符来表示(不能使用and和or)

布尔索引的结果总是生成数据的拷贝

5.神奇索引

神奇索引是NumPy中的术语,用于表述使用整数数组进行数据索引

利用神奇索引可以简单得到符合特定顺序的子集,甚至可以使用负的索引,将从尾部进行选择

>>> import numpy as np
>>> 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[[-1, -3, -4, -2]]

array([[7., 7., 7., 7.],
       [5., 5., 5., 5.],
       [4., 4., 4., 4.],
       [6., 6., 6., 6.]])

如果传递多个数组,就会索引出相应位置的元素

>>> arr[[1, 2, 4, 3], [2, 3, 2 ,1]]
array([1., 2., 4., 3.])

利用神奇索引可以得到矩阵数组中行列的子集所形成的矩形区域

例如:按照顺序选择arr中的1,7,2,5行中的前三行,列按照0,3,1,2列的顺序进行排列

>>> 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[[1, 7, 2, 5]][:3, [0, 3, 1, 2]]

array([[1., 1., 1., 1.],
       [7., 7., 7., 7.],
       [2., 2., 2., 2.]])

注意:神奇索引和切片不同,神奇索引总是返回数组的复制

6.数组的转置和换轴

对于简单的二维数组,可以直接使用T方法来得到转置数组

>>> arr
array([[ 2.59891831,  1.10909321, -0.26387971,  0.45109993,  0.38430929,
        -0.17000843],
       [-0.3513787 , -2.77342207,  0.82158585, -1.02533   , -0.10216791,
         0.3577984 ],
       [-1.33538454,  0.60345409, -0.03928757, -1.13104679,  1.59398506,
        -0.39949191],
       [ 2.6306111 ,  0.17122034,  0.09058392, -1.21850954, -1.0320289 ,
         0.61513253]])
>>> arr.T
array([[ 2.59891831, -0.3513787 , -1.33538454,  2.6306111 ],
       [ 1.10909321, -2.77342207,  0.60345409,  0.17122034],
       [-0.26387971,  0.82158585, -0.03928757,  0.09058392],
       [ 0.45109993, -1.02533   , -1.13104679, -1.21850954],
       [ 0.38430929, -0.10216791,  1.59398506, -1.0320289 ],
       [-0.17000843,  0.3577984 , -0.39949191,  0.61513253]])

对于更高维度的数组,transpose方法可以接受包含轴编号的远足,用于置换轴

>>> arr = arr.reshape((2, 3, 4))
>>> arr
array([[[ 2.59891831,  1.10909321, -0.26387971,  0.45109993],
        [ 0.38430929, -0.17000843, -0.3513787 , -2.77342207],
        [ 0.82158585, -1.02533   , -0.10216791,  0.3577984 ]],

       [[-1.33538454,  0.60345409, -0.03928757, -1.13104679],
        [ 1.59398506, -0.39949191,  2.6306111 ,  0.17122034],
        [ 0.09058392, -1.21850954, -1.0320289 ,  0.61513253]]])
>>> arr.transpose((1, 0, 2))
array([[[ 2.59891831,  1.10909321, -0.26387971,  0.45109993],
        [-1.33538454,  0.60345409, -0.03928757, -1.13104679]],

       [[ 0.38430929, -0.17000843, -0.3513787 , -2.77342207],
        [ 1.59398506, -0.39949191,  2.6306111 ,  0.17122034]],

       [[ 0.82158585, -1.02533   , -0.10216791,  0.3577984 ],
        [ 0.09058392, -1.21850954, -1.0320289 ,  0.61513253]]])

使用.T进行转置是环洲的一个特殊案例,ndarray有一个swapaxes方法,接收一对轴编号作为参数,并且对轴进行调整

>>> arr.reshape(2, 2, 4)
array([[[ 0.09717629, -2.17543887,  0.09990871,  1.49023416],
        [-1.27141933, -1.89522406, -0.02287714, -2.0027277 ]],

       [[ 1.49565981,  0.16066713, -1.30763266, -0.18619576],
        [ 0.98093828, -0.50549868,  0.29650228, -1.24413866]]])

>>> arr.swapaxes(0, 1)
array([[ 0.09717629, -1.27141933,  1.49565981,  0.98093828],
       [-2.17543887, -1.89522406,  0.16066713, -0.50549868],
       [ 0.09990871, -0.02287714, -1.30763266,  0.29650228],
       [ 1.49023416, -2.0027277 , -0.18619576, -1.24413866]])

猜你喜欢

转载自blog.csdn.net/weixin_43826242/article/details/88880524