当前位置:主页 > 查看内容

NumPy之:ndarray多维数组操作

发布时间:2021-05-19 00:00| 位朋友查看

简介:简介 NumPy一个非常重要的作用就是可以进行多维数组的操作 多维数组对象也叫做ndarray。我们可以在ndarray的基础上进行一系列复杂的数学运算。 本文将会介绍一些基本常见的ndarray操作 大家可以在数据分析中使用。 创建ndarray 创建ndarray有很多种方法 我们……
简介

NumPy一个非常重要的作用就是可以进行多维数组的操作 多维数组对象也叫做ndarray。我们可以在ndarray的基础上进行一系列复杂的数学运算。

本文将会介绍一些基本常见的ndarray操作 大家可以在数据分析中使用。

创建ndarray

创建ndarray有很多种方法 我们可以使用np.random来随机生成数据

import numpy as np
# Generate some random data
data np.random.randn(2, 3)
data
array([[ 0.0929, 0.2817, 0.769 ],
 [ 1.2464, 1.0072, -1.2962]])

除了随机创建之外 还可以从list中创建

data1 [6, 7.5, 8, 0, 1]
arr1 np.array(data1)
array([6. , 7.5, 8. , 0. , 1. ])

从list中创建多维数组

data2 [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 np.array(data2)
array([[1, 2, 3, 4],
 [5, 6, 7, 8]])

使用np.zeros创建初始值为0的数组

np.zeros(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

创建2维数组

np.zeros((3, 6))
array([[0., 0., 0., 0., 0., 0.],
 [0., 0., 0., 0., 0., 0.],
 [0., 0., 0., 0., 0., 0.]])

使用empty创建3维数组

np.empty((2, 3, 2))
array([[[0., 0.],
 [0., 0.],
 [0., 0.]],
 [[0., 0.],
 [0., 0.],
 [0., 0.]]])

注意 这里我们看到empty创建的数组值为0 其实并不是一定的 empty会从内存中随机挑选空间来返回 并不能保证这些空间中没有值。所以我们在使用empty创建数组之后 在使用之前 还要记得初始化他们。

使用arange创建范围类的数组

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

指定数组中元素的dtype

arr1 np.array([1, 2, 3], dtype np.float64)
arr2 np.array([1, 2, 3], dtype np.int32)
ndarray的属性

可以通过data.shape获得数组的形状。

data.shape
(2, 3)

通过ndim获取维数信息

arr2.ndim
2

可以通过data.dtype获得具体的数据类型。

data.dtype
dtype( float64 )
ndarray中元素的类型转换

在创建好一个类型的ndarray之后 还可以对其进行转换

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

上面我们使用astype将int64类型的ndarray转换成了float64类型的。

如果转换类型的范围不匹配 则会自动进行截断操作

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

注意 这里是把小数截断 并没有向上或者向下取整。

ndarray的数学运算

数组可以和常量进行运算 也可以和数组进行运算

arr np.array([[1., 2., 3.], [4., 5., 6.]])
arr * arr
array([[ 1., 4., 9.],
 [16., 25., 36.]])
arr 10
array([[11., 12., 13.],
 [14., 15., 16.]])
arr - arr
array([[0., 0., 0.],
 [0., 0., 0.]])
1 / arr
array([[1. , 0.5 , 0.3333],
 [0.25 , 0.2 , 0.1667]])
arr ** 0.5
array([[1. , 1.4142, 1.7321],
 [2. , 2.2361, 2.4495]])

数组之间还可以进行比较 比较的是数组中每个元素的大小

arr2 np.array([[0., 4., 1.], [7., 2., 12.]])
arr2 arr
array([[False, True, False],
 [ True, False, True]])
index和切片基本使用

先看下index和切片的基本使用 index基本上和普通数组的使用方式是一样的 用来访问数组中某一个元素。

切片要注意的是切片后返回的数组中的元素是原数组中元素的引用 修改切片的数组会影响到原数组。

# 构建一维数组
arr np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# index访问
arr[5]
# 切片访问
arr[5:8]
array([5, 6, 7])
# 切片修改
arr[5:8] 12
array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
# 切片可以修改原数组的值
arr_slice arr[5:8]
arr_slice[1] 12345
array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8,
# 构建二维数组
arr2d np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2]
array([7, 8, 9])
# index 二维数组
arr2d[0][2]
# index二维数组
arr2d[0, 2]
# 构建三维数组
arr3d np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
arr3d
array([[[ 1, 2, 3],
 [ 4, 5, 6]],
 [[ 7, 8, 9],
 [10, 11, 12]]])
# index三维数组
arr3d[0]
array([[1, 2, 3],
 [4, 5, 6]])
# copy是硬拷贝 和原数组的值相互不影响
old_values arr3d[0].copy()
arr3d[0] 42
arr3d
array([[[42, 42, 42],
 [42, 42, 42]],
 [[ 7, 8, 9],
 [10, 11, 12]]])
arr3d[0] old_values
arr3d
array([[[ 1, 2, 3],
 [ 4, 5, 6]],
 [[ 7, 8, 9],
 [10, 11, 12]]])
# index 三维数组
arr3d[1, 0]
array([7, 8, 9])
x arr3d[1]
array([[ 7, 8, 9],
 [10, 11, 12]])
array([7, 8, 9])
index with slice

slice还可以作为index使用 作为index使用表示的就是一个index范围值。

作为index表示的slice可以有多种形式。

有头有尾的 表示index从1开始到6-1结束

arr[1:6]
array([ 1, 2, 3, 4, 64])

无头有尾的 表示index从0开始 到尾-1结束

arr2d[:2]
array([[1, 2, 3],
 [4, 5, 6]])

有头无尾的 表示从头开始 到所有的数据结束

arr2d[:2, 1:]
array([[2, 3],
 [5, 6]])
arr2d[1, :2]
array([4, 5])
boolean index

index还可以使用boolean值 表示是否选择这一个index的数据。

我们先看下怎么构建一个boolean类型的数组

names np.array([ Bob , Joe , Will , Bob , Will , Joe , Joe ])
names Bob 
array([ True, False, False, True, False, False, False])

上面我们通过比较的方式返回了一个只包含True和False的数组。

这个数组可以作为index值来访问数组

# 构建一个7 * 4 的数组
data np.random.randn(7, 4)
array([[ 0.275 , 0.2289, 1.3529, 0.8864],
 [-2.0016, -0.3718, 1.669 , -0.4386],
 [-0.5397, 0.477 , 3.2489, -1.0212],
 [-0.5771, 0.1241, 0.3026, 0.5238],
 [ 0.0009, 1.3438, -0.7135, -0.8312],
 [-2.3702, -1.8608, -0.8608, 0.5601],
 [-1.2659, 0.1198, -1.0635, 0.3329]])
# 通过boolean数组来访问 
data[names Bob ]
array([[ 0.275 , 0.2289, 1.3529, 0.8864],
 [-0.5771, 0.1241, 0.3026, 0.5238]])

在索引行的时候 还可以索引列

data[names Bob , 3]
array([0.8864, 0.5238])

可以用 ~符号来取反

data[~(names Bob )]
array([[-2.0016, -0.3718, 1.669 , -0.4386],
 [-0.5397, 0.477 , 3.2489, -1.0212],
 [ 0.0009, 1.3438, -0.7135, -0.8312],
 [-2.3702, -1.8608, -0.8608, 0.5601],
 [-1.2659, 0.1198, -1.0635, 0.3329]])

我们可以通过布尔型数组设置值 在实际的项目中非常有用

data[data 0] 0
array([[0.275 , 0.2289, 1.3529, 0.8864],
 [0. , 0. , 1.669 , 0. ],
 [0. , 0.477 , 3.2489, 0. ],
 [0. , 0.1241, 0.3026, 0.5238],
 [0.0009, 1.3438, 0. , 0. ],
 [0. , 0. , 0. , 0.5601],
 [0. , 0.1198, 0. , 0.3329]])
data[names ! Joe ] 7
array([[7. , 7. , 7. , 7. ],
 [0. , 0. , 1.669 , 0. ],
 [7. , 7. , 7. , 7. ],
 [7. , 7. , 7. , 7. ],
 [7. , 7. , 7. , 7. ],
 [0. , 0. , 0. , 0.5601],
 [0. , 0.1198, 0. , 0.3329]])
Fancy indexing

Fancy indexing也叫做花式索引 它是指使用一个整数数组来进行索引。

举个例子 我们先创建一个 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]])

上面我们构建了一个8 * 4的数组。

arr[[1, 5, 7, 2], [0, 3, 1, 2]]
array([ 4, 23, 29, 10])

然后取他们的第2列的第一个值 第6列的第三个值等等。最后得到一个1维的数组。

数组变换

我们可以在不同维度的数组之间进行变换 还可以转换数组的轴。

reshape方法可以将数组转换成为任意的形状

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

数组还提供了一个T命令 可以将数组的轴进行对调

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

对于高维数组 可以使用transpose来进行轴的转置

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

上面的transpose((1, 0, 2)) 怎么理解呢

其含义是将x y轴对调 z轴保持不变。

上面我们通过使用reshape((2, 2, 4))方法创建了一个3维 也就是3个轴的数组。 其shape是 2 * 2 * 4 。

先看下对应关系

0 0 -》 [ 0, 1, 2, 3]

0 1 -》 [ 4, 5, 6, 7]

1 0 -》 [ 8, 9, 10, 11]

1 1 -》 [12, 13, 14, 15]

转换之后

0 0 -》 [ 0, 1, 2, 3]

0 1 -》 [ 8, 9, 10, 11]

1 0 -》[ 4, 5, 6, 7]

1 1 -》 [12, 13, 14, 15]

于是得到了我们上面的的结果。

多维数组的轴转换可能比较复杂 大家多多理解。

还可以使用 swapaxes 来交换两个轴 上面的例子可以重写为

arr.swapaxes(0,1)

本文已收录于 http://www.flydean.com/09-python-numpy-ndarray/

最通俗的解读 最深刻的干货 最简洁的教程 众多你不知道的小技巧等你来发现

欢迎关注我的公众号:「程序那些事」,懂技术 更懂你


本文转自网络,原文链接:https://developer.aliyun.com/article/784174
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐