转换 numpy 中的一组数字,以便每个数字都转换为其他一些小于它的数字 [英] Transform a set of numbers in numpy so that each number gets converted into a number of other numbers which are less than it

查看:31
本文介绍了转换 numpy 中的一组数字,以便每个数字都转换为其他一些小于它的数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一组数字:

In [8]: import numpy as np

In [9]: x = np.array([np.random.random() for i in range(10)])

In [10]: x
Out[10]: 
array([ 0.62594394,  0.03255799,  0.7768568 ,  0.03050498,  0.01951657,
        0.04767246,  0.68038553,  0.60036203,  0.3617409 ,  0.80294355])

现在我想通过以下方式将这个集合转换为另一个集合y:对于x中的每个元素i,对应的元素y 中的 j 将是 x 中小于 i 的其他元素的数量.例如,上面给出的 x 看起来像:

Now I want to transform this set into another set y in the following way: for every element i in x, the corresponding element j in y would be the number of other elements in x which are less than i. For example, the above given x would look like:

In [25]: y
Out[25]: array([ 6.,  2.,  8.,  1.,  0.,  3.,  7.,  5.,  4.,  9.])

现在,我可以使用简单的 python 循环来做到这一点:

Now, I can do this using simple python loops:

In [16]: for i in range(len(x)):
    ...:     tot = 0
    ...:     for j in range(len(x)):
    ...:         if x[i] > x[j]: tot += 1
    ...:     y[i] = int(tot)

然而,当x的长度很大时,代码会变得非常慢.我想知道是否可以使用任何麻木魔法来拯救.例如,如果我必须过滤所有小于 0.5 的元素,我会简单地使用布尔掩码:

However, when length of x is very large, the code becomes extremely slow. I was wondering if any numpy magic can be brought to rescue. For example, if I had to filter all the elements less than 0.5, I would have simply used a Boolean masking:

In [19]: z = x[x < 0.5]

In [20]: z
Out[20]: array([ 0.03255799,  0.03050498,  0.01951657,  0.04767246,  0.3617409 ])

是否可以使用类似的方法来更快地实现相同的目标?

Can something like this be used so that the same thing could be achieved much faster?

推荐答案

您实际需要做的是获取数组排序顺序的:

What you actually need to do is get the inverse of the sorting order of your array:

import numpy as np
x = np.random.rand(10)
y = np.empty(x.size,dtype=np.int64)
y[x.argsort()] = np.arange(x.size)

示例运行(在 ipython 中):

Example run (in ipython):

In [367]: x
Out[367]: 
array([ 0.09139335,  0.29084225,  0.43560987,  0.92334644,  0.09868977,
        0.90202354,  0.80905083,  0.4801967 ,  0.99086213,  0.00933582])

In [368]: y
Out[368]: array([1, 3, 4, 8, 2, 7, 6, 5, 9, 0])

<小时>

或者,如果您想获得 x 中每个对应元素的元素数量,则必须将排序从升序反转为降序.一种可能的选择是简单地交换索引的构造:


Alternatively, if you want to get the number of elements greater than each corresponding element in x, you have to reverse the sorting from ascending to descending. One possible option to do this is to simply swap the construction of the indexing:

y_rev = np.empty(x.size,dtype=np.int64)
y_rev[x.argsort()] = np.arange(x.size)[::-1]

另一个,正如@unutbu 在评论中所建议的,是将原始数组映射到新数组:

another, as @unutbu suggested in a comment, is to map the original array to the new one:

y_rev = x.size - y - 1

这篇关于转换 numpy 中的一组数字,以便每个数字都转换为其他一些小于它的数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆