numpy的argpartition如何在文档示例中工作?

Mel*_*Mel 8 python numpy

我想了解numpy的argpartition函数。我已使文档的示例尽可能基本。

import numpy as np

x = np.array([3, 4, 2, 1])
print("x: ", x)

a=np.argpartition(x, 3)
print("a: ", a)

print("x[a]:", x[a])
Run Code Online (Sandbox Code Playgroud)

这是输出...

('x: ', array([3, 4, 2, 1]))
('a: ', array([2, 3, 0, 1]))
('x[a]:', array([2, 1, 3, 4]))
Run Code Online (Sandbox Code Playgroud)

在a = np.argpartition(x,3)行中,第k个元素不是最后一个元素(数字1)吗?如果它是数字1,则x排序时1是否不应该成为第一个元素(元素0)?

在x [a]中,为什么2在1的“前面”是第一个元素?

我缺少什么基本的东西?

zvo*_*one 9

更完整的答案是什么argpartition确实是在文档中的分区,那人说:

创建数组的副本,并重新排列其元素,以使第k个位置的元素的值处于其在排序数组中的位置。所有小于第k个元素的元素都将在该元素之前移动,所有等于或大于第k个元素的元素都将移动到其后面。两个分区中元素的顺序未定义。

因此,对于输入数组3, 4, 2, 1,排序后的数组将为1, 2, 3, 4

的结果np.partition([3, 4, 2, 1], 3)将在第3个(即最后一个)元素中具有正确的值(即与排序数组相同)。第三个元素的正确值为4

让我针对所有的值对此进行说明,k以使其清楚:

  • np.partition([3, 4, 2, 1], 0)- [ 1,4,2,3]
  • np.partition([3, 4, 2, 1], 1)- [1,2,4,3]
  • np.partition([3, 4, 2, 1], 2)- [1,2,3,4]
  • np.partition([3, 4, 2, 1], 3)-[ 2,1,3,4 ]

换句话说:结果的第k个元素与排序数组的第k个元素相同。k之前的所有元素都小于或等于该元素。之后的所有元素都大于或等于它。

使用argpartition,除了argpartition返回索引可以用于形成相同的结果外,其他情况相同。


Imt*_*har 6

我记得我也很难弄清楚,也许文档写得不好,但这就是它的意思

当你这样做时,a=np.argpartition(x, 3)x 的排序方式是只有第 k 个索引处的元素才会被排序(在我们的例子中 k=3)

因此,当您运行这段代码时,您基本上是在问排序数组中第三个索引的值是多少。因此,输出是('x[a]:', array([2, 1, 3, 4]))仅对元素 3 进行排序的位置。

由于文档建议所有小于第 k 个元素的数字都在它之前(没有特定的顺序),因此您在 1 之前得到 2,因为它没有特定的顺序。

我希望这可以澄清它,如果您仍然感到困惑,请随时发表评论:)


DSe*_*al6 5

与@Imtinan 类似,我为此苦苦挣扎。我发现将函数分解为 arg 和分区很有用。

取以下数组:

array = np.array([9, 2, 7, 4, 6, 3, 8, 1, 5])

the corresponding indices are: [0,1,2,3,4,5,6,7,8] where 8th index = 5 and 0th = 9
Run Code Online (Sandbox Code Playgroud)

如果我们这样做np.partition(array, k=5),代码将采用第 5 个元素(不是索引),然后将其放入一个新数组中。然后它将把那些元素 < 5th 元素放在它之前,然后把那些 > 5th 元素放在之后,就像这样:

pseudo output: [lower value elements, 5th element, higher value elements]

如果我们计算这个,我们会得到:

array([3, 5, 1, 4, 2, 6, 8, 7, 9])

这是有道理的,因为原始数组中的第 5 个元素 = 6,[1,2,3,4,5] 都小于 6,而 [7,8,9] 大于 6。请注意,这些元素是无序的.

然后的 arg 部分np.argpartition()更进一步,将元素交换为它们在原始数组中的相应索引。所以如果我们这样做:

np.argpartition(array, 5) 我们将获得:

array([5, 8, 7, 3, 1, 4, 6, 2, 0])

从上面,原始数组有这个结构 [index=value] [0=9, 1=2, 2=7, 3=4, 4=6, 5=3, 6=8, 7=1, 8=5 ]

您可以将索引的值映射到输出,并且满足条件:

argpartition() = partition(), 像这样:

[索引形式] array([5, 8, 7, 3, 1, 4, 6, 2, 0]) 变为

[3, 5, 1, 4, 2, 6, 8, 7, 9]
Run Code Online (Sandbox Code Playgroud)

这与 的输出相同np.partition(array)

array([3, 5, 1, 4, 2, 6, 8, 7, 9])
Run Code Online (Sandbox Code Playgroud)

希望这是有道理的,这是我了解函数的 arg 部分的唯一方法。