在 numpy 中转换一组数字,以便每个数字转换成小于它的多个其他数字

2025-04-15 09:18:00
admin
原创
33
摘要:问题描述:考虑一组数字: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...

问题描述:

考虑一组数字:

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,方法如下:对于i中的每个元素,中的x对应元素就是 中小于 的其他元素的数量。例如,上面给出的集合如下所示:j`yxi`x

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

现在,我可以使用简单的 Python 循环来完成此操作:

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非常大时,代码会变得非常慢。我想知道是否有任何 Numpy 魔法可以解决这个问题。例如,如果我必须过滤所有小于 的元素0.5,我只需使用布尔掩码即可:

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

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

是否可以使用类似的东西来更快地实现同样的事情?


解决方案 1:

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

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 中):

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,则必须将排序从升序反转为降序。一种可行的方法是简单地交换索引的构造:

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

另一个方法是将原始数组映射到新数组:

y_rev = x.size - y - 1

解决方案 2:

以下是使用以下方法的一种方法np.searchsorted-

np.searchsorted(np.sort(x),x)

另一个主要基于@Andras Deak's solution使用argsort()-

x.argsort().argsort()

样本运行 -

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

In [360]: np.searchsorted(np.sort(x),x)
Out[360]: array([6, 2, 8, 1, 0, 3, 7, 5, 4, 9])

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

解决方案 3:

除了其他答案之外,使用布尔索引的另一种解决方案可能是:

sum(x > i for i in x)

例如:

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])

In [10]: y = sum(x > i for i in x)
In [11]: y
Out[10]: array([6, 2, 8, 1, 0, 3, 7, 5, 4, 9])

解决方案 4:

我想通过对@Andras Deak 的解决方案进行一些测试来为这篇文章做出贡献argsort


对于短数组来说,似乎argsortagain 更快。简单的想法是评估我们看到平衡偏移的数组的长度。

我将定义三个函数

  • construct这是 Andras Deak 的解决方案

  • argsortagain这是显而易见的

  • attempted_optimal这权衡了len(a) == 400

函数

def argsortagain(s):
    return s.argsort()

def construct(s):
    u = np.empty(s.size, dtype=np.int64)
    u[s] = np.arange(s.size)

    return u

def attempted_optimal(s):
    return argsortagain(s) if len(s) < 400 else construct(s)

测试

results = pd.DataFrame(
    index=pd.RangeIndex(10, 610, 10, 'len'),
    columns=pd.Index(['construct', 'argsortagain', 'attempted_optimal'], name='function'))

for i in results.index:
    a = np.random.rand(i)
    s = a.argsort()
    for j in results.columns:
        results.set_value(
            i, j,
            timeit(
                '{}(s)'.format(j),
                'from __main__ import {}, s'.format(j),
                number=10000)
        )

results.plot()

在此处输入图片描述

结论

attempted_optimal它确实完成了它该做的事情。但我不确定它在阵列长度(低于 400)范围内获得的边际效益是否值得,因为在这种范围内,阵列长度几乎无关紧要。我完全支持constructed只使用一个。

这个分析帮助我得出了这个结论。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用