一系列 numpy 操作似乎依赖于 numpy 数组初始化
Series of numpy operations seem to depend on numpy arrays initialization
我正在用 numpy 数组向量化一系列操作。在这样做的过程中,我在不同的代码执行中得到了不同的结果。我正在使用 numpy.random.randn
来获取我需要的形状的 numpy 数组,并测试我的操作是否按照我希望的方式进行。我有时会得到想要的结果,有时却得不到,即使是同一系列的操作。
理论上,第一行big_result
应该等于result_1
,而第二行等于result_2
。有时会发生这种情况。其他时候第一行是正确的,而第二行不是。而其他时候,两者都是错误的。
这是重现问题的代码(我添加了一些我亲手得到的种子,其中有错误发生,有的则没有):
import numpy as np
np.random.seed(2) # First row of big_result corresponds to result_1, the rest is wrong
np.random.seed(3) # First row of big_result corresponds to result_1, the rest is wrong
np.random.seed(4) # Both rows of big_result are ok
# My two vectors
a = np.random.randn(1000, 8)
b = np.random.randn(500, 8)
# Operation vector
c = np.random.randn(3, 6, 8)
# Matrix with both a, b
big_A = np.full((2, 1000, 8), np.nan)
big_A[0, :, :] = a
big_A[1, :500, :] = b
# Broadcasting used to enable the use of c with big_A
big_C = np.broadcast_to(c, (2, 3, 6, 8)).reshape((3, 6, 2, 8))
# First result (for a)
result_1 = np.linalg.norm(a[:, np.newaxis] - c[:, np.newaxis, :], axis=-1)
result_1 = np.min(result_1[np.newaxis], axis=(-1, 1)) # Shape: (1, 1000)
# Second result (for b)
result_2 = np.linalg.norm(b[:, np.newaxis] - c[:, np.newaxis, :], axis=-1)
result_2 = np.min(result_2[np.newaxis], axis=(-1, 1)) # Shape: (1, 500)
# I mask out this operation to avoid meddling of NaN values
arr_with_nan = big_A[np.newaxis] - big_C[:, :, :, np.newaxis]
arr_with_nan = np.ma.array(arr_with_nan, mask=np.isnan(arr_with_nan))
# Result for both a and b
big_result = np.linalg.norm(arr_with_nan, axis=-1)
big_result = np.min(big_result[np.newaxis], axis=2)
big_result = np.min(big_result, axis=1)[0] # Shape: (2, 1000), where (1,) -> result_1; (2,) -> result_2
一些评论
a
和 b
对应于 axis=1
中维度可能不同的 numpy 数组。这就是为什么我将它们附加到一个大的 numpy 矩阵 big_A
和 np.nan
中以填充值。另外,我的“操作向量”c
正在广播到形状 (2, 3, 6, 8)
以便它可以用于 big_A
内的 a
和 b
.这个广播不允许我立即操作big_C
和big_A
,所以我不得不将big_C
重塑为(3, 6, 2, 8)
。
我猜我正在处理一个舍入错误。我试过用 .astype(np.float32 or np.float64)
投射所有内容,但它不起作用。如果我随后执行我的代码,它就会失败。如何确保我的代码独立于 a
和 b
中的初始值工作?
编辑:我忘了添加我的确切问题。
broadcast_to
后不要重塑。如果必须转置,或使用 big_C[:,:,None,:]
制作 (2,3,1,6,8)
我正在用 numpy 数组向量化一系列操作。在这样做的过程中,我在不同的代码执行中得到了不同的结果。我正在使用 numpy.random.randn
来获取我需要的形状的 numpy 数组,并测试我的操作是否按照我希望的方式进行。我有时会得到想要的结果,有时却得不到,即使是同一系列的操作。
理论上,第一行big_result
应该等于result_1
,而第二行等于result_2
。有时会发生这种情况。其他时候第一行是正确的,而第二行不是。而其他时候,两者都是错误的。
这是重现问题的代码(我添加了一些我亲手得到的种子,其中有错误发生,有的则没有):
import numpy as np
np.random.seed(2) # First row of big_result corresponds to result_1, the rest is wrong
np.random.seed(3) # First row of big_result corresponds to result_1, the rest is wrong
np.random.seed(4) # Both rows of big_result are ok
# My two vectors
a = np.random.randn(1000, 8)
b = np.random.randn(500, 8)
# Operation vector
c = np.random.randn(3, 6, 8)
# Matrix with both a, b
big_A = np.full((2, 1000, 8), np.nan)
big_A[0, :, :] = a
big_A[1, :500, :] = b
# Broadcasting used to enable the use of c with big_A
big_C = np.broadcast_to(c, (2, 3, 6, 8)).reshape((3, 6, 2, 8))
# First result (for a)
result_1 = np.linalg.norm(a[:, np.newaxis] - c[:, np.newaxis, :], axis=-1)
result_1 = np.min(result_1[np.newaxis], axis=(-1, 1)) # Shape: (1, 1000)
# Second result (for b)
result_2 = np.linalg.norm(b[:, np.newaxis] - c[:, np.newaxis, :], axis=-1)
result_2 = np.min(result_2[np.newaxis], axis=(-1, 1)) # Shape: (1, 500)
# I mask out this operation to avoid meddling of NaN values
arr_with_nan = big_A[np.newaxis] - big_C[:, :, :, np.newaxis]
arr_with_nan = np.ma.array(arr_with_nan, mask=np.isnan(arr_with_nan))
# Result for both a and b
big_result = np.linalg.norm(arr_with_nan, axis=-1)
big_result = np.min(big_result[np.newaxis], axis=2)
big_result = np.min(big_result, axis=1)[0] # Shape: (2, 1000), where (1,) -> result_1; (2,) -> result_2
一些评论
a
和 b
对应于 axis=1
中维度可能不同的 numpy 数组。这就是为什么我将它们附加到一个大的 numpy 矩阵 big_A
和 np.nan
中以填充值。另外,我的“操作向量”c
正在广播到形状 (2, 3, 6, 8)
以便它可以用于 big_A
内的 a
和 b
.这个广播不允许我立即操作big_C
和big_A
,所以我不得不将big_C
重塑为(3, 6, 2, 8)
。
我猜我正在处理一个舍入错误。我试过用 .astype(np.float32 or np.float64)
投射所有内容,但它不起作用。如果我随后执行我的代码,它就会失败。如何确保我的代码独立于 a
和 b
中的初始值工作?
编辑:我忘了添加我的确切问题。
broadcast_to
后不要重塑。如果必须转置,或使用 big_C[:,:,None,:]
制作 (2,3,1,6,8)