Python 'order=0的'scipy.ndimage.zoom()'的意外行为`
我很难理解order=0时的行为 考虑以下代码:Python 'order=0的'scipy.ndimage.zoom()'的意外行为`,python,numpy,scipy,zooming,ndimage,Python,Numpy,Scipy,Zooming,Ndimage,我很难理解order=0时的行为 考虑以下代码: import numpy as np import scipy as sp import scipy.ndimage arr = np.arange(3) + 1 print(arr) for order in range(5): zoomed = sp.ndimage.zoom(arr.astype(float), 4, order=order) print(order, np.round(zoomed, 3)) 其输出为:
import numpy as np
import scipy as sp
import scipy.ndimage
arr = np.arange(3) + 1
print(arr)
for order in range(5):
zoomed = sp.ndimage.zoom(arr.astype(float), 4, order=order)
print(order, np.round(zoomed, 3))
其输出为:
0 [1. 1. 1. 2. 2. 2. 2. 2. 2. 3. 3. 3.]
1 [1. 1.182 1.364 1.545 1.727 1.909 2.091 2.273 2.455 2.636 2.818 3. ]
2 [1. 1.044 1.176 1.394 1.636 1.879 2.121 2.364 2.606 2.824 2.956 3. ]
3 [1. 1.047 1.174 1.365 1.601 1.864 2.136 2.399 2.635 2.826 2.953 3. ]
4 [1. 1.041 1.162 1.351 1.59 1.86 2.14 2.41 2.649 2.838 2.959 3. ]
因此,当order=0
时,值(预期)不会插值。
但是,我希望:
[1. 1. 1. 1. 2. 2. 2. 2. 3. 3. 3. 3.]
i、 e.每个值的元素数完全相同,因为缩放是一个整数。
因此,我期望得到与以下相同的结果:
为什么每个元素重复的次数会有变化
请注意,
np.repeat()
不能直接处理多维数组,这就是我希望从scipy.ndimage.zoom()中获得“正确”行为的原因
我的NumPy和SciPy版本是:
print(np.__version__)
# 1.17.4
print(sp.__version__)
# 1.3.3
我发现:
这指向了scipy.ndimage.zoom()的一些意外行为,但我不太确定观察到的效果是否相同。我认为这是预期的行为
考虑一下您的初始列表,[1,2,3]
。您要求scipy将其放大4倍,从而创建一个4x3=12个元素的列表。列表的第一个元素必须是1,最后一个元素必须是3。然后,对于2,我们有偶数个元素,所以将2作为第6和第7元素是有意义的。这就给出了[1,2,2,3]
。从这里开始,您提供了顺序为0的zoom,这意味着zoom将使用顺序为0的样条线来填充缺少的值。第一种情况下,zoom需要填充4个介于1和2之间的缺失值。这必须是[1,1,2,2]
。第二种情况下,2和3之间缺少4个值。同样的逻辑,[2,2,3,3]
。最终结果[1,1,1,2,2,2,2,2,3,3]
现在考虑一个5X变焦,它生成一个15元素数组。同样的故事,只是有一个“中间”元素,所以最初只有一个2被放在新列表的第8位。每对之间有六个元素要填充,我们得到的逻辑是相同的
[1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3]
因此,您得到的2s比1s或3s多,因为2涉及两个插值操作,而不是1和3的一个插值操作 我认为这是预期的行为
考虑一下您的初始列表,[1,2,3]
。您要求scipy将其放大4倍,从而创建一个4x3=12个元素的列表。列表的第一个元素必须是1,最后一个元素必须是3。然后,对于2,我们有偶数个元素,所以将2作为第6和第7元素是有意义的。这就给出了[1,2,2,3]
。从这里开始,您提供了顺序为0的zoom,这意味着zoom将使用顺序为0的样条线来填充缺少的值。第一种情况下,zoom需要填充4个介于1和2之间的缺失值。这必须是[1,1,2,2]
。第二种情况下,2和3之间缺少4个值。同样的逻辑,[2,2,3,3]
。最终结果[1,1,1,2,2,2,2,2,3,3]
现在考虑一个5X变焦,它生成一个15元素数组。同样的故事,只是有一个“中间”元素,所以最初只有一个2被放在新列表的第8位。每对之间有六个元素要填充,我们得到的逻辑是相同的
[1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3]
因此,您得到的2s比1s或3s多,因为2涉及两个插值操作,而不是1和3的一个插值操作 这是一个bin/edge数组解释问题。
scipy.ndimage.zoom()
的行为基于数组值的边缘解释,而为整数缩放因子(模仿np.repeat()
)生成大小相同的块的行为基于bin解释
让我们用一些“图片”来说明
Bin解释
考虑数组[1 2 3]
,让我们将每个值分配给一个bin。
每个箱子的边缘将是:0
和1
用于1
,1
和2
用于2
,等等
0 1 2 3
|1|2|3|
现在,让我们将此数组缩放4倍:
1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2
| 1 | 2 | 3 |
1 1
0 1 2 3 4 5 6 7 8 9 0 1
| | | | | | | | | | | |
1 2 3
因此,使用“隔壁邻居”方法分配给料仓的值为:
1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2
|1 1 1 1|2 2 2 2|3 3 3 3|
1 1
0 1 2 3 4 5 6 7 8 9 0 1
| | | | | | | | | | | |
1 1 1 2 2 2 2 2 2 3 3 3
边缘解释
考虑与前面相同的数组[1 2 3]
,但现在让我们将每个值分配给一条边:
0 1 2
| | |
1 2 3
现在,让我们将此数组缩放4倍:
1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2
| 1 | 2 | 3 |
1 1
0 1 2 3 4 5 6 7 8 9 0 1
| | | | | | | | | | | |
1 2 3
因此,要使用“隔壁邻居”方法指定给边的值为:
1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2
|1 1 1 1|2 2 2 2|3 3 3 3|
1 1
0 1 2 3 4 5 6 7 8 9 0 1
| | | | | | | | | | | |
1 1 1 2 2 2 2 2 2 3 3 3
而边3
被分配给2
,因为2
具有位置5.5
,而1
具有位置0
和(5.5-3=2.5)
。
类似地,边8
被分配给2
,因为(8-5.5=2.5)<(11-8=3)
评论
在物理学中,“面元阵列解释”通常更有用,因为测量通常是“在适当的域中对某个面元进行某种积分的结果”(特别是在给定的时间间隔收集的任何形式的信号,包括图像),因此我希望对scipy.ndimage.zoom()进行“面元解释”)
但我承认“边缘解释”同样有效(尽管我不确定哪些应用程序从中受益最多)
(感谢@Patol75将我指向右侧)这是一个bin/edge数组解释问题。
scipy.ndimage.zoom()
的行为基于数组值的边缘解释,而为整数缩放因子(模仿np.repeat()
)生成大小相同的块的行为基于bin解释
让我们用一些“图片”来说明
Bin解释
考虑数组[1 2 3]
,让我们将每个值分配给一个bin。
每个箱子的边缘应为:0