一文掌握numpy数组的创建索引和切片操作

Posted 非晚非晚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文掌握numpy数组的创建索引和切片操作相关的知识,希望对你有一定的参考价值。

1. numpy数组的创建

1.1 array函数创建数组

最简单也是最直观的方式,就是使用array函数直接创建numpy数组。

import numpy as np

ndarray = np.array([1, 2, 3, 4])
print(ndarray) # [1 2 3 4]

ndarray = np.array(list('abcdefg'))
print(ndarray) # ['a' 'b' 'c' 'd' 'e' 'f' 'g']

ndarray = np.array([[11, 22, 33, 44], [10, 20, 30, 40]])
print(ndarray)
'''
[[11 22 33 44]
 [10 20 30 40]]
'''

1.2 asarray函数创建数组

asarray将输入转换为ndarray,如果输入本身就是一个ndarray就不进行复制。

当数据源是ndarray时,array与asarray的区别:array仍然会copy出一个副本,占用新的内存,但asarray不会

当数据源是其它类型时,asarray与array的效果一致。

import numpy as np

a=np.random.random((3,3))
b=np.array(a,dtype='float64')
c=np.asarray(a,dtype='float64')
a[2]=2
print(a)
'''
[[0.4593994  0.94093065 0.25819247]
 [0.29774257 0.32810293 0.31841724]
 [2.         2.         2.        ]]
'''
print(b)
'''
[[0.4593994  0.94093065 0.25819247]
 [0.29774257 0.32810293 0.31841724]
 [0.45421249 0.85030328 0.98043655]]
'''
print(c)
'''
[[0.4593994  0.94093065 0.25819247]
 [0.29774257 0.32810293 0.31841724]
 [2.         2.         2.        ]]
'''

1.3 zeros和zeros_like创建数组

  • zeros:表示直接创建全零数组
  • zeros_like:根据传入的ndarray数组的shape来创建所有元素为0的数组
import numpy as np

ndarray = np.zeros(10)
print(ndarray) # [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

ndarray = np.zeros((2, 2))
print(ndarray)
'''
[[0. 0.]
 [0. 0.]]
 '''

ndarray = np.array([[11, 22, 33, 44], [10, 20, 30, 40]])
ndarray1 = np.zeros_like(ndarray)
print(ndarray1)
'''
[[0 0 0 0]
 [0 0 0 0]]
'''

1.4 ones和ones_like创建数组

用于创建所有元素都为1的数组.ones_like用法同zeros_like用法

import numpy as np

ndarray = np.ones(10)
print(ndarray) # [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

ndarray = np.ones((2, 2))
print(ndarray)
'''
[[1. 1.]
 [1. 1.]]
 '''

ndarray = np.array([[11, 22, 33, 44], [10, 20, 30, 40]])
ndarray1 = np.ones_like(ndarray)
print(ndarray1)
'''
[[1 1 1 1]
 [1 1 1 1]]
'''

1.5 empty和empty_like创建数组

用于创建空数组,空数据中的值并不为0,而是未初始化的随机值.

import numpy as np

ndarray = np.empty(3)
print(ndarray) # [1.96589195e-316 0.00000000e+000 1.58101007e-322]

ndarray = np.empty((2, 2))
print(ndarray)
'''
[[1.9638129e-316 0.0000000e+000]
 [7.9050503e-323 7.9050503e-323]]
 '''

ndarray = np.array([[11, 22, 33, 44], [10, 20, 30, 40]])
ndarray1 = np.empty_like(ndarray)
print(ndarray1)
'''
[[              0               0 139955131091248 139957403317784]
 [139957403322480 139955459383168 139955130963144 139955459420264]]
'''

1.6 arange创建数组

arange函数是python内置函数range函数的数组版本。

import numpy as np

ndarray = np.arange(10)
print(ndarray) # [0 1 2 3 4 5 6 7 8 9]

ndarray = np.arange(10,20)
print(ndarray) # [10 11 12 13 14 15 16 17 18 19]

ndarray = np.arange(10,20,2)
print(ndarray) # [10 12 14 16 18]

1.7 linspace创建数组

numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下:

np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数说明
start序列的起始值
stop序列的终止值,如果endpoint为true,该值包含于数列中
num要生成的等步长的样本数量,默认为50
endpoint该值为 true 时,数列中包含stop值,反之不包含,默认是True。
retstep如果为 True 时,生成的数组中会显示间距,反之不显示。
dtypendarray 的数据类型

代码举例:

import numpy as np
a = np.linspace(1,10,10)
print(a) #[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]

1.8 eye、identity创建对角数组

eye与identity都可以生成部分元素为1,其余为0的数组,不同的是,identity只能创建方阵,且对角为1,而eye不只能创建方阵,而且可以指定1的偏移位置,它们的区别如下。

np.identity(n, dtype=None)

#k = 0居中,1向上偏离1,2偏离2以此类推,-1向下偏离
np.eye(N, M=None, k=0, dtype=<typefloat'>) 

代码举例:

import numpy as np

ndarray = np.identity(4)
print(ndarray)

'''
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
'''

ndarray = np.eye(4,k=1) #1的位置向上偏移1
print(ndarray)
'''
[[0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]
 [0. 0. 0. 0.]]
'''

2. 索引与切片

索引顺序和列表顺序一直,如下图所示。

2.1 一维数组

一维数组很简单,基本和列表一致。它们的区别在于数组切片是原始数组视图,而列表为浅拷贝。(这就意味着对于数组,如果做任何修改,原始也会跟着更改,),这也意味着,如果不想更改原始数组,我们需要进行显式的复制,从而得到它的副本(.copy())。

import numpy as np

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

# 索引与切片
print(arr[4]) #索引 ;值为==》4
print(arr[3:6])#切片:==》[3 4 5]

# copy
arr_old_nocopy = arr # [0 1 2 3 4 5 6 7 8 9]
arr_old_copy = arr.copy() # [0 1 2 3 4 5 6 7 8 9]
arr[3:6] = 33 #更新值
print(arr) # [ 0  1  2 33 33 33  6  7  8  9]
print(arr_old_copy) # [0 1 2 3 4 5 6 7 8 9]
print(arr_old_nocopy) # [ 0  1  2 33 33 33  6  7  8  9]

2.2 二维数组

二维数组中,如果[ ]内只有一个元素,则取的是一个一维数组。如果想要取值,则需要使用两个[]或者用逗号隔开行和列

import numpy as np

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

#索引和切片
#索引行
print(arr[0]) #索引 行==》[1 2 3]
print(arr[0,:]) #索引 行==》[1 2 3]
print(arr[0,...]) #索引 行==》[1 2 3]
#索引列
print(arr[:,1]) #索引 列==》[2 5 8]
print(arr[... , 1]) #索引 列==》[2 5 8]
#取得一个二维数组
print(arr[0:2,1:2])# 注意左闭右开
'''
[[2]
 [5]]
'''
# 设置步长的索引
print(arr[::2,::2]) #设置步长为2
'''
[[1 3]
 [7 9]]
'''
#取值
print(arr[1,2]) #索引取值==》6
print(arr[1][2]) #索引取值==》6

2.3 多维数组

这个和而二维数组一样理解,只不过它是多维数组。

import numpy as np

arr = np.arange(12)
arr = arr.reshape(2,2,3) #将arr变为2×2×3数组
#print(arr)
'''
[[[ 0  1  2]
  [ 3  4  5]]

 [[ 6  7  8]
  [ 9 10 11]]]
'''

print(arr[0])
'''
索引==》
[[0 1 2]
 [3 4 5]]
'''

#取值
print(arr[1,0,1]) #索引取值==》7
print(arr[1][0][1]) #索引取值==》7

print(arr[0,1]) # 索引==》[3 4 5]
arr[0] = 100 #赋值
print(arr)
'''
[[[100 100 100]
  [100 100 100]]

 [[  6   7   8]
  [  9  10  11]]]
'''

2.4 布尔型索引

先来看一个列子:

import numpy as np

arr = (np.arange(36)).reshape(6,6)#生成6*6的数组
print(arr)
'''
[[ 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 32 33 34 35]]
'''
x = np.array([0, 1, 2, 1, 4, 5])
arr1 = np.array(x==1)
print(arr1) # [False  True False  True False False]
print(arr[x==1])#取出为True的行
'''
[[ 6  7  8  9 10 11]
 [18 19 20 21 22 23]]
'''
  • 从结果上看,布尔索引取出了布尔值为True的行。
  • 布尔型数组的长度和索引的数组的行数(轴长度)必须一致。
  • 布尔型数组可与切片,整数(整数序列)一起使用。
import numpy as np

arr = (np.arange(36)).reshape(6,6)#生成6*6的数组

x = np.array([0, 1, 2, 1, 4, 5])

print(arr[x == 1,2:]) #切片:取出等于1的行,且列从索引2至末端
'''
[[ 8  9 10 11]
 [20 21 22 23]]
'''

print(arr[x == 1,-3:]) # 切片:取出等于1的行,且列从-3开始至末端
'''
[[ 9 10 11]
 [21 22 23]]
'''
print(arr[x==1,3])#切片:取出等于1的行,列为3 ==》[ 9 21]

同理,可以使用不等于、大于、小于等操作进行索引与切片。

2.5 花式索引

花式索引(Fancy indexing),指的是利用整数数组进行索引。

  • 传入单个列表或数组
import numpy as np

arr = np.empty((8,4))# 创建新数组,只分配内存空间,不填充值

for i in range(8):#从0开始,每一行递增
    arr[i] = i

print(arr[[2,6,1]]) #使用列表取需要的行
#这个顺序,就是我们所传入的整数列表或者ndarray。
'''
[[2. 2. 2. 2.]
 [6. 6. 6. 6.]
 [1. 1. 1. 1.]]
'''
print(arr[[-2,-6,-1]]) #负号索引
'''
[[6. 6. 6. 6.]
 [2. 2. 2. 2.]
 [7. 7. 7. 7.]]
'''
  • 传入多个索引数组

会返回一个一维数组,其中的元素对应各个索引元素

import numpy as np

arr = np.arange(35).reshape(5,7)#生成一个5*7的数组
print(arr)
'''
[[ 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 32 33 34]]
'''
print(arr[[1,3,2,4],[2,0,6,5]]) # [ 9 21 20 33]
# 其实就是(1,2),(3,0)...

同理多维数组的花式索引也是一样的。

以上是关于一文掌握numpy数组的创建索引和切片操作的主要内容,如果未能解决你的问题,请参考以下文章

Numpy数组对象的操作-索引机制切片和迭代方法

numpy数组的索引和切片

学习NumPy全套代码超详细基本操作数据类型数组运算复制和试图索引切片和迭代形状操作通用函数线性代数

python数据分析基础之Numpy库详解

python数据分析基础之Numpy库详解

科学计算基础软件包NumPy入门讲座:操作数组