210812周四上午 from炎蓉
""" 实验1:np.transpose 只是引用
b的修改,影响到a了,a也被修改。
说明b并没有拷贝数据,只是重新修改了索引规则,数据仍然是a。
a创建的时候(只要矩阵不是太大)数据默认是连续的,但对于b来说,数据存储并不是连续的。
"""
import numpy as np
a = np.zeros((3, 3))
a[0] = [1, 2, 3]
print(a)
b = a.transpose()
b[0, 0] = 4
print(a)
[[1. 2. 3.]
[0. 0. 0.]
[0. 0. 0.]]
[[4. 2. 3.]
[0. 0. 0.]
[0. 0. 0.]]
""" 实验2:ascontiguousarray 可能是引用也可能是拷贝
数据不连续会创建一个新矩阵,数据连续则还是引用。
"""
c = np.ascontiguousarray(a)
c[0, 0] = 5
print(a)
d = np.ascontiguousarray(b)
d[0, 0] = 6
print(a)
[[5. 2. 3.]
[0. 0. 0.]
[0. 0. 0.]]
[[5. 2. 3.]
[0. 0. 0.]
[0. 0. 0.]]
""" 实验3:transpose一般会破坏连续性,但不绝对。
如果要明确拷贝新数据,使用ascontiguousarray是不明智的。
"""
e = np.zeros(3)
f = e.transpose()
g = np.ascontiguousarray(f) # f连续,ascontiguousarray并没有发生拷贝
g[0] = 7 # 此时g的修改会影响到e
print(e)
[7. 0. 0.]
""" 实验4:这里拷贝新数据是次要目的,最主要的还是为了确保数据连续性,让后面的运算效率更高。
矩阵乘法就有这种操作:https://blog.csdn.net/gogdizzy/article/details/9003369
术语叫:优化cache命中
知道意思就行,这个比较底层了,不用深究
(这里py的测试不明显,没测出效果)
"""
from pyxllib.xl import PerfTest
class IndexOrderTest(PerfTest):
def __init__(self):
self.n = 1000
self.a = np.zeros((self.n, self.n))
self.b = self.a.transpose()
def perf_1(self):
for i in range(self.n):
for j in range(self.n):
self.a[i, j] + 1
def perf_2(self):
for i in range(self.n):
for j in range(self.n):
self.b[i, j] + 1
IndexOrderTest().perf(repeat=10)
1 用时(秒) 总和: 5.351 均值标准差: 0.535±0.146 总数: 10 最小值: 0.398 最大值: 0.909
2 用时(秒) 总和: 5.367 均值标准差: 0.537±0.091 总数: 10 最小值: 0.406 最大值: 0.700