移位值 np.apply_along_axis returns 不一致的结果
Shifting values with np.apply_along_axis returns inconsistent results
TL;DR: np.apply_along_axis
适用于形状为 (1561, 338)
的特定数组,它是另一个形状为 (351225, 338)
的数组的子集,但它失败了。
我正在尝试应用以下功能:
def add_min(a):
return a + abs(a.min()) if a.min() < 0 else a
x_train
的形状为 (1561, 15, 15, 338)
(n * height * width * channels) 并且我需要将所有值都转换为正数才能记录规范化我的数据。出于显而易见的原因,我想按频道执行此操作。
现在,如果我重塑 x_train:x_train = x_train.reshape(-1, 338)
并获得形状 (351225, 338)
我应该能够执行:
x_train = np.apply_along_axis(add_min, 0, x_train)
然而...
之前:
x_train.min()
>> -2147483648
之后:
x_train.min()
>> -2147370103
换句话说,它不起作用。另一方面,如果我只保留中心像素:
# Keep the center value of axes (1, 2)
x_train = x_train[:, x_train.shape[1]//2, x_train.shape[2]//2, :]
x_train.shape
>> (1561, 338)
x_train.min()
>> -32768 # strange coincidence that this location in the image has a much smaller value range
x_train = np.apply_along_axis(add_min, 0, x_train)
x_train.min()
>> 0
我认为这与较大的负值有关,因为如果我 select 在 2 个中心轴(即 1 和 8)而不是中间 (7, 7) 中的随机索引,我再次分别在 np.apply_along_axis
之前和之后获得 -2147483648 和 -2147369934 的 x_train.min()
。
那我做错了什么?有没有更好的方法可以实现我的目标?
如果问题是“随机的”,int32
上的溢出是一个很好的猜测。但是使用 apply_along_axis
可能会使诊断问题变得更加困难,因为它将您的函数包装在一个(晦涩的)迭代中。使用整个数组计算来诊断事物应该更容易。
制作一个混合了 min
个值的适度数组:
In [77]: A = np.random.randint(-50,1000,(4,8))
In [78]: A
Out[78]:
array([[151, 531, 765, 379, 89, 499, 818, 848],
[873, -12, -45, 900, 416, 838, 603, 849],
[540, 0, 1, 589, 297, 566, 688, 556],
[ 53, 170, 461, -16, -6, 480, 321, 392]])
你的函数:
In [79]: np.apply_along_axis(add_min, 0, A)
Out[79]:
array([[151, 543, 810, 395, 95, 499, 818, 848],
[873, 0, 0, 916, 422, 838, 603, 849],
[540, 12, 46, 605, 303, 566, 688, 556],
[ 53, 182, 506, 0, 0, 480, 321, 392]])
让我们创建一个等效的全数组。首先找到规格为axis
的min
:
In [80]: am = np.min(A, axis=0, keepdims=True)
In [81]: am
Out[81]: array([[ 53, -12, -45, -16, -6, 480, 321, 392]])
现在创建一个模仿您的函数的移位数组(没有仅适用于标量的 if
):
In [82]: shift=np.abs(am)
In [83]: shift[am>=0]=0
In [84]: shift
Out[84]: array([[ 0, 12, 45, 16, 6, 0, 0, 0]])
In [85]: A+shift
Out[85]:
array([[151, 543, 810, 395, 95, 499, 818, 848],
[873, 0, 0, 916, 422, 838, 603, 849],
[540, 12, 46, 605, 303, 566, 688, 556],
[ 53, 182, 506, 0, 0, 480, 321, 392]])
还有其他方法可以实现这种转变,但适用相同的基本思想,使用 am<0
确定哪些列得到转变。
这样也会更快。
TL;DR: np.apply_along_axis
适用于形状为 (1561, 338)
的特定数组,它是另一个形状为 (351225, 338)
的数组的子集,但它失败了。
我正在尝试应用以下功能:
def add_min(a):
return a + abs(a.min()) if a.min() < 0 else a
x_train
的形状为 (1561, 15, 15, 338)
(n * height * width * channels) 并且我需要将所有值都转换为正数才能记录规范化我的数据。出于显而易见的原因,我想按频道执行此操作。
现在,如果我重塑 x_train:x_train = x_train.reshape(-1, 338)
并获得形状 (351225, 338)
我应该能够执行:
x_train = np.apply_along_axis(add_min, 0, x_train)
然而...
之前:
x_train.min()
>> -2147483648
之后:
x_train.min()
>> -2147370103
换句话说,它不起作用。另一方面,如果我只保留中心像素:
# Keep the center value of axes (1, 2)
x_train = x_train[:, x_train.shape[1]//2, x_train.shape[2]//2, :]
x_train.shape
>> (1561, 338)
x_train.min()
>> -32768 # strange coincidence that this location in the image has a much smaller value range
x_train = np.apply_along_axis(add_min, 0, x_train)
x_train.min()
>> 0
我认为这与较大的负值有关,因为如果我 select 在 2 个中心轴(即 1 和 8)而不是中间 (7, 7) 中的随机索引,我再次分别在 np.apply_along_axis
之前和之后获得 -2147483648 和 -2147369934 的 x_train.min()
。
那我做错了什么?有没有更好的方法可以实现我的目标?
如果问题是“随机的”,int32
上的溢出是一个很好的猜测。但是使用 apply_along_axis
可能会使诊断问题变得更加困难,因为它将您的函数包装在一个(晦涩的)迭代中。使用整个数组计算来诊断事物应该更容易。
制作一个混合了 min
个值的适度数组:
In [77]: A = np.random.randint(-50,1000,(4,8))
In [78]: A
Out[78]:
array([[151, 531, 765, 379, 89, 499, 818, 848],
[873, -12, -45, 900, 416, 838, 603, 849],
[540, 0, 1, 589, 297, 566, 688, 556],
[ 53, 170, 461, -16, -6, 480, 321, 392]])
你的函数:
In [79]: np.apply_along_axis(add_min, 0, A)
Out[79]:
array([[151, 543, 810, 395, 95, 499, 818, 848],
[873, 0, 0, 916, 422, 838, 603, 849],
[540, 12, 46, 605, 303, 566, 688, 556],
[ 53, 182, 506, 0, 0, 480, 321, 392]])
让我们创建一个等效的全数组。首先找到规格为axis
的min
:
In [80]: am = np.min(A, axis=0, keepdims=True)
In [81]: am
Out[81]: array([[ 53, -12, -45, -16, -6, 480, 321, 392]])
现在创建一个模仿您的函数的移位数组(没有仅适用于标量的 if
):
In [82]: shift=np.abs(am)
In [83]: shift[am>=0]=0
In [84]: shift
Out[84]: array([[ 0, 12, 45, 16, 6, 0, 0, 0]])
In [85]: A+shift
Out[85]:
array([[151, 543, 810, 395, 95, 499, 818, 848],
[873, 0, 0, 916, 422, 838, 603, 849],
[540, 12, 46, 605, 303, 566, 688, 556],
[ 53, 182, 506, 0, 0, 480, 321, 392]])
还有其他方法可以实现这种转变,但适用相同的基本思想,使用 am<0
确定哪些列得到转变。
这样也会更快。