我试图理解numpy的argpartition函数。我已经使documentation的示例尽可能基本。
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])
这是输出...
('x: ', array([3, 4, 2, 1]))
('a: ', array([2, 3, 0, 1]))
('x[a]:', array([2, 1, 3, 4]))
在a = np.argpartition(x,3)行中,第k个元素不是最后一个元素(数字1)吗?如果它是数字1,则x排序时1是否不应该成为第一个元素(元素0)?
在x [a]中,为什么2是1的第一个元素“在前面”?
我缺少什么基本的东西?
答案 0 :(得分:5)
对argpartition所做的工作的更完整答案是在partition的文档中,并且说:
创建数组的副本,其元素以这种方式重新排列 位于第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
返回可用于形成相同结果的索引。
答案 1 :(得分:3)
类似于@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
如果我们执行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。请注意,这些元素没有命令。
然后,np.argpartition()
的arg部分进一步向前移动,将元素交换为原始数组中的相应索引。因此,如果我们这样做:
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()
,如下所示:
[索引格式]数组([5,8,7,3,1,4,6,2,0])变为
[3, 5, 1, 4, 2, 6, 8, 7, 9]
与np.partition(array)
的输出
array([3, 5, 1, 4, 2, 6, 8, 7, 9])
希望这是有道理的,这是我可以理解函数的arg部分的唯一方法。
答案 2 :(得分:1)
我还记得我也很难弄清楚,也许文档写得不好,但这是什么意思,当您执行@RequestMapping(value = "goods",method = RequestMethod.GET)
public String deleteByIds(@RequestBody Integer[] ids) {
goodsService.deleteByIds(ids);
return "ok";
}
时,x的排序方式是仅位置中的元素3,在这种情况下,k将被排序,因此,当您运行此代码时,基本上是说排序数组的第三个索引是什么,因此输出a=np.argpartition(x, 3)
是因为对4(element 3)进行了排序,并且正如该文档建议的所有数字都小于其之前的数字(无特定顺序),因此您在数字前1之前有2,因为其无特定顺序,所以我希望可以澄清这一点,如果您仍然感到困惑,请随时发表评论:)< / p>