得到了一个如下所示的数组:
x = array([['PP Mango', 0.25, 0.75, 'PP'],
['PP Nectarine', 0.25, 0.75, 'PP'],
['Lemon', 0.25, 0.75, 'Loose'],
['PP Peach', 0.25, 0.75, 'PP'],
['Orange Navel', 0.25, 0.75, 'Loose'],
['PP Cherries', 0.25, 0.75, 'PP']], dtype=object)
我尝试将这个多维数组的第4个元素x[:,3]
排序为降序***,而不改变原始行顺序***,其中x[:,3]
是一个字符串(它将始终是'PP
'或'Loose
')。
- 已试密码:**
x[x[:,3].argsort()][::-1] #but this shuffles the original array row order within 4th element which should not happen
- 预期产出:**
x = array([['PP Mango', 0.25, 0.75, 'PP'],
['PP Nectarine', 0.25, 0.75, 'PP'],
['PP Peach', 0.25, 0.75, 'PP'],
['PP Cherries', 0.25, 0.75, 'PP'],
['Lemon', 0.25, 0.75, 'Loose'],
['Orange Navel', 0.25, 0.75, 'Loose']], dtype=object)
5条答案
按热度按时间1dkrff031#
使用列表排序,只使用一个排序键比较第4个元素是否为"松散"。
python
sort
的稳定性保证了它不会在不需要的时候移动元素。印刷品:
这是一个非numpy的解决方案,但它可以工作。然后转换回numpy数组:
array(lst)
7hiiyaii2#
像前面的答案一样从NumPy到Python再回到NumPy似乎相当愚蠢/低效。NumPy也有稳定的排序,你只需要请求它:
请注意,我现在删除了您的冲销。结果是:
现在我们如何在'Loose'之前得到'PP'呢?一种方法是像Jean-François did一样将列与'Loose'进行比较,因为这会将'Loose'变为True,将'PP'变为False,并且False小于True:
或者检查中的是否与“PP”相等:
两者都返回所需的结果:
还有一种方法是获取“PP”行,获取非“PP”行,并对它们进行vstack:
如果你有两个以上不同的值,或者未知的值,那么相等(不相等)的比较技巧就不够用了,那该怎么做呢?NumPy * 不像Python * 那样有一个漂亮的
reverse=True
,但是我们可以像Python一样来实现它,它在实际排序之前和之后都是反向的。在NumPy中有一种方法可以做到:在网上试试吧!(所有四个解决方案)
xam8gpfp3#
对发布的解决方案进行基准测试,包括示例数组和大型数组(从示例中随机选择100000行)。
我不知道为什么我的NumPy解决方案在你的小例子中比其他解决方案占用更多的内存,而在大数组中占用更少的内存,我猜NumPy解决方案有一些小的常量开销。
完整代码(尝试在线!):
jv4diomz4#
以下要求提供以下测试的完整结果无法作为评论发布,因此作为答案发布:
为了公平地比较所有方法的结果下面的排序时间,但是代码做了一些改动,所以纯Python方法不需要在numpy之间来回转换,看起来numpy可能不是处理小数组的正确方法。
对我来说仍然是一个惊喜的是,Kelly_vstack在100000行时没有赢得Kelly版本,在6行时真的很糟糕。
转换为numpy的前后时序如下:
表明对于小阵列,前向和后向转换执行得与Numpy解决方案相当好。
为了真正全面地了解下面的主题,使用
.sort()
代替sorted()
的纯Python就地排序的计时,与numpy相比,在一个非常大的数组的情况下,显示了纯Python版本计时的较小差异,以及对于小数组的出色计时(比最好的numpy版本快4倍):下面是用于获得上述结果的完整代码,这些代码可以很容易地用于显示使用和不使用Python/numpy转换进行排序的时间:
af7jpaap5#
你只需要使用一个排序键,即指定排序算法在尝试对数组元素进行排序时要比较什么。这里你希望键是每行的最后一个元素,所以:
应该会给予你想要的输出。注意使用
reverse=True
来获得相反顺序的数据。