11.1 Numpy切片
"""
思考:通过切片,我们可以选取多个元素,但是,如果我们要选取的低维数组(或元素)是不连续的,该怎么做呢?
切片操作是在原始数组上创建一个视图view,这只是访问数组数组的一种方式。因此,原始数组不会被复制到内存中,传递
的是一个类似引用的东西,与 astype() 方法是两个不同的拷贝方式。
"""
import numpy as np
a = np.arange(1, 10)
print(a)
print(a[:3]) # [1 2 3]
print(a[3:6]) # [4 5 6]
print(a[6:]) # [7 8 9]
print(a[::-1]) # [9 8 7 6 5 4 3 2 1]
print(a[:-4:-1]) # [9 8 7]
print(a[-4:-7:-1]) # [6 5 4]
print(a[-7::-1]) # [3 2 1]
print(a[::]) # [1 2 3 4 5 6 7 8 9]
print(a[::3]) # [1 4 7]
print(a[1::3]) # [2 5 8]
print(a[2::3]) # [3 6 9]
b = np.arange(20).reshape(4, 5)
print(b)
'''
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
'''
# 第二行,第三列
print(b[2, 3]) # 13
# 第0-5行,第1列
print(b[0:5, 1]) # [ 1 6 11 16]
# 所有行,第1列
print(b[:, 1]) # [ 1 6 11 16]
# 第1-3行,第1列
print(b[1:3, 1]) # [ 6 11]
# 第1行
print(b[1]) # [5 6 7 8 9]
# 倒数第1列
print(b[-1]) # [15 16 17 18 19]
# 思考:如何将一个二维数组的所有元素,全部倒序过来呢?
x = np.arange(30).reshape(5, 6)
print(x)
"""
[[ 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]]
[[29 28 27 26 25 24]
[23 22 21 20 19 18]
[17 16 15 14 13 12]
[11 10 9 8 7 6]
[ 5 4 3 2 1 0]]
"""
print(x[::-1, ::-1])
"""
python和numpy的切片相比
"""
# python中的切片时浅拷贝(互不影响)
li = [1, 3, 3, 4, 5]
li2 = li[:]
li[0] = 100
print(li, li2)
"""
[100, 3, 3, 4, 5] [1, 3, 3, 4, 5]
"""
# numpy中的切片是视图(相互影响)
x = np.arange(30).reshape(5, 6)
y = x[0:3, 0:3]
y[0][0] = 100
print(x, y)
"""
[[100 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]]
[[100 1 2]
[ 6 7 8]
[ 12 13 14]]
"""
"""
注意:ndarray数组切片,返回的是原数组的视图。但是,这种视图是共享底层的数据,并不是一种赋值
"""
# 引用并不相同
print(x is y) # False
# 如何实现底层数据的复制呢?通过数组对象的copy方法,实现底层数据的复制,而不是返回底层数据的视图
y = x.copy()
x[0][0] = 100
print(x, y)
print(x is y) # False
"""
[[100 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]]
[[100 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]]
"""
import copy
aa = [1, 3, [2, 3]]
# 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。
bb = aa.copy() # 浅拷贝
bb[0] = 99
bb[2].append(100)
print('浅拷贝', aa, bb)
print('浅拷贝', id(aa), id(bb)) # 2139811873544 2139811852168
cc = [1, 2, 3]
# 赋值是把原对象的引用给了新的对象
dd = cc
dd[0] = 200
print('直接赋值',cc, dd)
print('直接赋值',id(cc), id(dd)) # 3116606419528 3116606419528
cc = [1, 2, 3]
# 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。
dd = copy.deepcopy(cc)
dd[0] = 33
print('深拷贝', cc, dd)
print('深拷贝', id(cc), id(dd)) #2139811800328 2139811802056