210812周四上午 from炎蓉

    1. """ 实验1:np.transpose 只是引用
    2. b的修改,影响到a了,a也被修改。
    3. 说明b并没有拷贝数据,只是重新修改了索引规则,数据仍然是a。
    4. a创建的时候(只要矩阵不是太大)数据默认是连续的,但对于b来说,数据存储并不是连续的。
    5. """
    6. import numpy as np
    7. a = np.zeros((3, 3))
    8. a[0] = [1, 2, 3]
    9. print(a)
    10. b = a.transpose()
    11. b[0, 0] = 4
    12. print(a)

    [[1. 2. 3.]
    [0. 0. 0.]
    [0. 0. 0.]]
    [[4. 2. 3.]
    [0. 0. 0.]
    [0. 0. 0.]]

    1. """ 实验2:ascontiguousarray 可能是引用也可能是拷贝
    2. 数据不连续会创建一个新矩阵,数据连续则还是引用。
    3. """
    4. c = np.ascontiguousarray(a)
    5. c[0, 0] = 5
    6. print(a)
    7. d = np.ascontiguousarray(b)
    8. d[0, 0] = 6
    9. print(a)

    [[5. 2. 3.]
    [0. 0. 0.]
    [0. 0. 0.]]
    [[5. 2. 3.]
    [0. 0. 0.]
    [0. 0. 0.]]

    1. """ 实验3:transpose一般会破坏连续性,但不绝对。
    2. 如果要明确拷贝新数据,使用ascontiguousarray是不明智的。
    3. """
    4. e = np.zeros(3)
    5. f = e.transpose()
    6. g = np.ascontiguousarray(f) # f连续,ascontiguousarray并没有发生拷贝
    7. g[0] = 7 # 此时g的修改会影响到e
    8. print(e)

    [7. 0. 0.]

    1. """ 实验4:这里拷贝新数据是次要目的,最主要的还是为了确保数据连续性,让后面的运算效率更高。
    2. 矩阵乘法就有这种操作:https://blog.csdn.net/gogdizzy/article/details/9003369
    3. 术语叫:优化cache命中
    4. 知道意思就行,这个比较底层了,不用深究
    5. (这里py的测试不明显,没测出效果)
    6. """
    7. from pyxllib.xl import PerfTest
    8. class IndexOrderTest(PerfTest):
    9. def __init__(self):
    10. self.n = 1000
    11. self.a = np.zeros((self.n, self.n))
    12. self.b = self.a.transpose()
    13. def perf_1(self):
    14. for i in range(self.n):
    15. for j in range(self.n):
    16. self.a[i, j] + 1
    17. def perf_2(self):
    18. for i in range(self.n):
    19. for j in range(self.n):
    20. self.b[i, j] + 1
    21. 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