Numpy数组合并

2024-05-16 19:13:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我不熟悉Numpy,正在尝试使用一个示例合并排序程序,我在:http://interactivepython.org/runestone/static/pythonds/SortSearch/TheMergeSort.html

但是,当我尝试在numpy数组上使用它时:

blist = np.array([54, 26, 93, 17, 77, 31, 44, 55, 20])
mergeSort(blist)

打印出来了

^{pr2}$

而不是正常python列表的预期输出。有人知道为什么这个程序似乎不能和numpy数组一起工作,而可以使用它的预期输入吗?在


Tags: orgnumpyhttp示例htmlstatic数组runestone
2条回答

这个问题引起了我的兴趣,但我不确定这是否是学习numpy的好方法。像这样的迭代过程不能很好地利用数组的独特特性。它只是把它当作一个单子来对待,很明显,这种匹配并不完全正确。在


下面是一个小名单:

In [608]: alist=[3,2];arr=np.array(alist)
In [609]: mergeSort(alist)
Splitting  [3, 2]
Splitting  [3]
Merging  [3]
Splitting  [2]
Merging  [2]
Merging  [2, 3]

In [610]: mergeSort(arr)
Splitting  [3 2]
Splitting  [3]
Merging  [3]
Splitting  [2]
Merging  [2]
Merging  [2 2]

区别在于最后的合并步骤。在


我修改了代码以添加更多的诊断指纹

^{pr2}$

运行:

In [623]: alist=[3,2];arr=np.array(alist)
In [624]: mergeSort(alist)
Splitting  [3, 2]
Splitting  [3]
Merging  [3]
Splitting  [2]
Merging  [2]
2 0 0 [2, 2]
3 0 1 [2, 3]
Merging  [2, 3]

In [625]: mergeSort(arr)
Splitting  [3 2]
Splitting  [3]
Merging  [3]
Splitting  [2]
Merging  [2]
2 0 0 [2 2]
3 0 1 [2 2]
Merging  [2 2]

因此,对于列表,它是在1和4处“合并”,在数组中是在2和3处“合并”。我们能找出原因吗?我怀疑if测试中存在差异。在


看来修复方法是:

    lefthalf = alist[:mid].copy()
    righthalf = alist[mid:].copy()

正如@duhamp在数组中所指出的,对lefthalf的更改会改变righthalf。对于列表,lefthalf和{}是{}的副本。但是索引alist[:mid]返回view,而不是副本。这是列表和数组之间的一个重要区别。在

更重要的是,当您遇到Python代码的问题,尤其是numpy代码时,它有助于在可疑的问题点添加诊断打印。您可以使用调试器,或者像我们一样临时修改代码。不管怎样,问题通常是在编写代码时忽略了的细节。在

如前所述,不期望为列表编写的代码也能泛化为NumPy数组。在

如果要对NumPy数组排序,可以使用sorted()

blist = np.array([54, 26, 93, 17, 77, 31, 44, 55, 20])
print(sorted(blist))

问题在于合并函数为数组分配新值的方式。如果运行此程序,您可以看到问题:

^{pr2}$

似乎lefthalf引用了alist数组中的值,因此,alist值的赋值也同时改变了lefthalf的值。在

运行此代码块会使其更加明显:

alist = np.array([54,26])
mid = len(alist)//2
lefthalf = alist[:mid]
righthalf = alist[mid:]
print(lefthalf,"lefthalf before the incorrect assignment")
alist[0]=righthalf[0]
print(lefthalf,"lefthalf after the incorrect assignment") 

讨论了这个问题here。实际上,您可以通过在lefthalf = alist[:mid]righthalf = alist[mid:]之后添加.copy(),即lefthalf = alist[:mid].copy()等来修复它

相关问题 更多 >