我有一个float/int的numpy数组,并希望将其元素映射到它们的列中。在
如果一个数组没有重复项,这个问题可以通过下面的代码来解决
In [49]: a1
Out[49]: array([ 0.1, 5.1, 2.1, 3.1, 4.1, 1.1, 6.1, 8.1, 7.1, 9.1])
In [50]: a1.argsort().argsort()
Out[50]: array([0, 5, 2, 3, 4, 1, 6, 8, 7, 9])
现在我想将这个方法扩展到可能有重复项的数组,以便将重复项映射到相同的值。例如,我想要数组a
^{pr2}$映射到
0 1 4 5 6 1 7 8 8 1
或者到
0 3 4 5 6 3 7 9 9 3
或者到
0 2 4 5 6 2 7 8.5 8.5 2
在第一种/第二种情况下,如果我们只应用a2.argsort().argsort(),我们会将副本映射到其中的最小/最大等级。 第三种情况只是前两种情况的平均值。在
有什么建议吗?在
编辑(效率要求)
在最初的描述中,我忘了提到时间要求。我正在寻找解决方案,在numpy/scipy函数方面可以避免“纯python开销”。为了说明这一点,请考虑Richard提出的解决方案,该方案实际上解决了问题,但速度很慢:
def argsortdup(a1):
sorted = np.sort(a1)
ranked = []
for item in a1:
ranked.append(sorted.searchsorted(item))
return np.array(ranked)
In [86]: a2 = np.array([ 0.1, 1.1, 2.1, 3.1, 4.1, 1.1, 6.1, 7.1, 7.1, 1.1])
In [87]: %timeit a2.argsort().argsort()
1000000 loops, best of 3: 1.55 us per loop
In [88]: %timeit argsortdup(a2)
10000 loops, best of 3: 25.6 us per loop
In [89]: a = np.arange(0.1, 1000.1)
In [90]: %timeit a.argsort().argsort()
10000 loops, best of 3: 24.5 us per loop
In [91]: %timeit argsortdup(a)
1000 loops, best of 3: 1.14 ms per loop
In [92]: a = np.arange(0.1, 10000.1)
In [93]: %timeit a.argsort().argsort()
1000 loops, best of 3: 303 us per loop
In [94]: %timeit argsortdup(a)
100 loops, best of 3: 11.9 ms per loop
从上面的分析可以明显看出,argsortdup比a.argsort().argsort()慢30-50倍。主要原因是python循环和列表的使用。在
这里有一个函数可以返回您想要的输出(在第一种情况下)
基本上,你对它进行排序,然后搜索项目所在的索引。假设重复,则应返回第一个实例索引。我用你的a2例子测试了一下
^{pr2}$收益率
“a2测试”:
使用
unique
和bincount
可以做得相当好:或者,对于最低级别:
^{pr2}$通过给
bincount
提供要提供的箱子数量,有一个小的加速:在升级到最新版本的}和{}这两种方法都要快。在
scipy
后,正如评论中@WarrenWeckesser所建议的那样,scipy.stats.rankdata
似乎比{相关问题 更多 >
编程相关推荐