将数组排序到索引数组指定的容器中的最有效方法?

2023-11-24

任务举例:

data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
idx  = np.array([2, 0, 1, 1, 2, 0, 1, 1, 2])

预期结果:

binned = np.array([2, 6, 3, 4, 7, 8, 1, 5, 9])

限制条件:

  • 应该很快。

  • 应该O(n+k)其中 n 是数据的长度,k 是 bin 的数量。

  • 应该是稳定的,即箱内的顺序被保留。

显而易见的解决方案

data[np.argsort(idx, kind='stable')]

is O(n log n).

O(n+k)解决方案

def sort_to_bins(idx, data, mx=-1):
    if mx==-1:
        mx = idx.max() + 1
    cnts = np.zeros(mx + 1, int)
    for i in range(idx.size):
        cnts[idx[i] + 1] += 1
    for i in range(1, cnts.size):
        cnts[i] += cnts[i-1]
    res = np.empty_like(data)
    for i in range(data.size):
        res[cnts[idx[i]]] = data[i]
        cnts[idx[i]] += 1
    return res

是循环和缓慢的。

纯粹有更好的方法吗numpy < scipy < pandas < numba/pythran?


以下是一些解决方案:

  1. Use np.argsort不管怎样,毕竟它是快速编译的代码。

  2. Use np.bincount获取垃圾箱尺寸和np.argpartition这是O(n)对于固定数量的垃圾箱。缺点:目前没有稳定的算法可用,因此我们必须对每个 bin 进行排序。

  3. Use scipy.ndimage.measurements.labeled_comprehension。这大致满足了要求,但不知道它是如何实现的。

  4. Use pandas。我是一个完整的pandas菜鸟,所以我在这里使用的拼凑而成groupby可能不是最理想的。

  5. Use scipy.sparse压缩稀疏行和压缩稀疏列格式之间的切换恰好实现了我们正在寻找的确切操作。

  6. Use pythran(我敢肯定numba也适用)在问题中的循环代码上。所需要做的就是在 numpy import 之后插入到顶部

.

#pythran export sort_to_bins(int[:], float[:], int)

然后编译

# pythran stb_pthr.py

基准 100 个 bin,项目数量可变:

enter image description here

带回家:

如果你没问题numba/pythran这就是要走的路,如果不是的话scipy.sparse规模相当好。

Code:

import numpy as np
from scipy import sparse
from scipy.ndimage.measurements import labeled_comprehension
from stb_pthr import sort_to_bins as sort_to_bins_pythran
import pandas as pd

def sort_to_bins_pandas(idx, data, mx=-1):
    df = pd.DataFrame.from_dict(data=data)
    out = np.empty_like(data)
    j = 0
    for grp in df.groupby(idx).groups.values():
        out[j:j+len(grp)] = data[np.sort(grp)]
        j += len(grp)
    return out

def sort_to_bins_ndimage(idx, data, mx=-1):
    if mx==-1:
        mx = idx.max() + 1
    out = np.empty_like(data)
    j = 0
    def collect(bin):
        nonlocal j
        out[j:j+len(bin)] = np.sort(bin)
        j += len(bin)
        return 0
    labeled_comprehension(data, idx, np.arange(mx), collect, data.dtype, None)
    return out

def sort_to_bins_partition(idx, data, mx=-1):
    if mx==-1:
        mx = idx.max() + 1
    return data[np.argpartition(idx, np.bincount(idx, None, mx)[:-1].cumsum())]

def sort_to_bins_partition_stable(idx, data, mx=-1):
    if mx==-1:
        mx = idx.max() + 1
    split = np.bincount(idx, None, mx)[:-1].cumsum()
    srt = np.argpartition(idx, split)
    for bin in np.split(srt, split):
        bin.sort()
    return data[srt]

def sort_to_bins_sparse(idx, data, mx=-1):
    if mx==-1:
        mx = idx.max() + 1    
    return sparse.csr_matrix((data, idx, np.arange(len(idx)+1)), (len(idx), mx)).tocsc().data

def sort_to_bins_argsort(idx, data, mx=-1):
    return data[idx.argsort(kind='stable')]

from timeit import timeit
exmpls = [np.random.randint(0, K, (N,)) for K, N in np.c_[np.full(16, 100), 1<<np.arange(5, 21)]]

timings = {}
for idx in exmpls:
    data = np.arange(len(idx), dtype=float)
    ref = None
    for x, f in (*globals().items(),):
        if x.startswith('sort_to_bins_'):
            timings.setdefault(x.replace('sort_to_bins_', '').replace('_', ' '), []).append(timeit('f(idx, data, -1)', globals={'f':f, 'idx':idx, 'data':data}, number=10)*100)
            if x=='sort_to_bins_partition':
                continue
            if ref is None:
                ref = f(idx, data, -1)
            else:
                assert np.all(f(idx, data, -1)==ref)

import pylab
for k, v in timings.items():
    pylab.loglog(1<<np.arange(5, 21), v, label=k)
pylab.xlabel('#items')
pylab.ylabel('time [ms]')
pylab.legend()
pylab.show()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将数组排序到索引数组指定的容器中的最有效方法? 的相关文章

  • 如何使用我自己的自定义表单覆盖 django-rest-auth 中的表单?

    我正在使用 django rest auth 并尝试通过覆盖表单的方法之一来修复密码重置视图中的错误 尽管我已经使用不同的 django rest auth 表单成功完成了类似的操作 但我无法让它在这个表单上工作 无论我做什么 都会使用旧的
  • Python 中 time.sleep 和多线程的问题

    我对 python 中的 time sleep 函数有疑问 我正在运行一个脚本 需要等待另一个程序生成 txt 文件 虽然 这是一台非常旧的机器 所以当我休眠 python 脚本时 我遇到了其他程序不生成文件的问题 除了使用 time sl
  • 如何调试 numpy 掩码

    这个问题与this one https stackoverflow com q 73672739 11004423 我有一个正在尝试矢量化的函数 这是原来的函数 def aspect good angle float planet1 goo
  • Karasuba算法递归过多

    我正在尝试用 c 实现 Karasuba 乘法算法 但现在我只是想让它在 python 中工作 这是我的代码 def mult x y b m if max x y lt b return x y bm pow b m x0 x bm x1
  • Pandas如何按时间段过滤DataFrame

    我有一个包含下表的文件 Name AvailableDate totalRemaining 0 X3321 2018 03 14 13 00 00 200 1 X3321 2018 03 14 14 00 00 200 2 X3321 20
  • 无法在我的程序中使用 matplotlib 函数

    我正在 Windows 10 中运行 Anaconda 安装 conda 版本 4 3 8 这是我尝试在 python 命令行中运行的代码 import matplotlib pyplot as plt x 1 2 3 4 y 5 6 7
  • 如何仅注释堆积条形图的一个类别

    我有一个数据框示例 如下所示 data Date 2021 07 18 2021 07 19 2021 07 20 2021 07 21 2021 07 22 2021 07 23 Invalid NaN 1 1 NaN NaN NaN N
  • 同一台机器上有多个Python版本?

    Python 网站上是否有关于如何在 Linux 上的同一台计算机上安装和运行多个版本的 Python 的官方文档 我可以找到无数的博客文章和答案 但我想知道是否有 标准 官方方法可以做到这一点 或者这一切都取决于操作系统 我认为它是完全独
  • Python:“直接”调用方法是否实例化对象?

    我是 Python 新手 在对我的对象进行单元测试时 我注意到一些 奇怪 的东西 class Ape object def init self print ooook def say self s print s def main Ape
  • 使用 Windows 任务计划程序安排 [Virtualenv 相关] Python 脚本

    I want to schedule a python script to start at 3AM and break at 5PM every weekday However the problem arises when I need
  • python中将对象数据类型转换为字符串问题

    如何将对象数据类型结构转换为字符串数据类型 下面的方法不起作用 该列仍然存在object转换为字符串后 astype import pandas as pd df pd DataFrame country A B C D E df dtyp
  • 如何全局安装 Python(开发)依赖项,以便我不必在每个 venv 中重新安装它们?

    我希望在为每个项目创建的每个 venv 虚拟环境 中都可以使用一些 Python 依赖项 例如 black flake8 和 pytest 这可能吗 如果可以 如何实现 我想安装这三个once在我的主要 Python 安装下 我必须在启动新
  • 更新 matplotlib 中颜色条的范围

    我想更新一个contourf在函数内绘制 效果很好 然而 数据的范围发生了变化 因此我还必须更新颜色条 这就是我未能做到的地方 请参阅以下最小工作示例 import matplotlib pyplot as plt import numpy
  • 操作错误:尝试在 ubuntu 服务器中写入只读数据库

    我正在使用 FlaskApp 运行mod wsgi and apache2在 Ubuntu 服务器上 我尝试运行烧瓶应用程序localhost成功 然后部署到ubuntu服务器上 但是当我尝试更新数据库时 出现错误 Failed to up
  • 无法将matplotlib安装到pycharm

    我最近开始使用Python速成课程学习Python编程 我陷入困境 因为我无法让 matplotlib 在 pycharm 中工作 我已经安装了pip 我已经通过命令提示符使用 pip 安装了 matplotlib 现在 当我打开 pych
  • 使用 Numpy 进行多维批量图像卷积

    在图像处理和分类网络中 一个常见的任务是输入图像与一些固定滤波器的卷积或互相关 例如 在卷积神经网络 CNN 中 这是一种极其常见的操作 我已将通用版本任务减少为 Given 一批 N 个图像 N H W D 和一组 K 个滤镜 K H W
  • 如何在supervisord中设置组?

    因此 我正在设置 Supervisord 并尝试控制多个进程 并且一切正常 现在我想设置一个组 以便我可以启动 停止不同的进程集 而不是全部或全无 这是我的配置文件的片段 group tapjoy programs tapjoy game1
  • python 日志记录替代方案 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 蟒蛇记录模块 http docs python org library logging html使用起来
  • 如何在 Qt 中以编程方式制作一条水平线

    我想弄清楚如何在 Qt 中制作一条水平线 这很容易在设计器中创建 但我想以编程方式创建一个 我已经做了一些谷歌搜索并查看了 ui 文件中的 xml 但无法弄清楚任何内容 ui 文件中的 xml 如下所示
  • PYTHON:从 txt 文件中删除 POS 标签

    我有以下 txt 文件 其中包含 POS 词性 http en wikipedia org wiki Part of speech tagging 每个单词的标签 不用 jj到 说 vb 我 ppss是 bedz愤怒 jj在 在 dt无与伦

随机推荐

  • 英特尔 64 和 IA-32 |原子操作包括获取/释放语义

    根据 Intel 64 和 IA 32 架构软件开发人员手册 LOCK 信号前缀 确保处理器在信号置位时独占使用任何共享内存 这可以是总线或高速缓存锁的形式 但是 这就是我问这个问题的原因 我不清楚这个前缀是否也提供任何内存障碍 我正在多处
  • Visual Studio 绿色下划线 _ (不是绿色波浪线)

    Visual Studio 2013 经常用绿色 绿色下划线 标记我的代码 它代表什么 是否有与之相关的功能 例如自动完成或智能感知 这是自动大括号完成功能Visual Studio 2013 中引入 尽管如此 就像 Visual Stud
  • 如何让 Django 从 unicode 字符创建 slug?

    Django Unicode Slug 如何实现 class NewsModel models Model title models CharField max length 300 slug models CharField max le
  • ConcurrentHashMap 返回一个弱一致性迭代器,我们为什么要使用它呢?

    我正在阅读 Java Concurrency in Practice 这本书 第 85 页第 5 2 1 节讨论了 ConcurrentHashMap 及其优点 然而 书中的一部分声称 ConcurrentHashMap 返回的迭代器是弱一
  • Nest.js 无法解析依赖关系

    我正在尝试使用ConfigService in my users module ts但我得到了 错误 Nest 无法解析 UsersService UserRepository HttpService 的依赖项 请确保索引 2 处的参数 C
  • iOS 7中根据单元格文本计算单元格高度

    有许多解决方案使用 sizeWithFont 或类似的东西 但从 iOS 7 开始 它已被弃用 这是我到目前为止拼凑起来的一些代码 高度发生了变化 但一点也不准确 UITableViewCell tableView UITableView
  • Angular 5 一个域中的多个 Service Worker

    我在同一域的两个应用程序中有两个服务工作者 都是 Angular 5 里面的一个 前端 后端 内的第二个 我正在使用 angular service worker 包来管理服务工作者 当我构建产品版本并部署我的应用程序时 会发生一些奇怪的事
  • sh 中的“${0%/*}”和“${0##*/}”[重复]

    这个问题在这里已经有答案了 这些是brew 命令的摘录 BREW FILE DIRECTORY chdir 0 pwd P export HOMEBREW BREW FILE BREW FILE DIRECTORY 0 What do 0
  • 使用 React Native WebSockets 发送 Cookie

    所以我使用的是本机反应网络套接字但不知道如何在 websocket 中包含 cookie 有什么建议吗 目前还没有自动的方法来做到这一点 WebSocket 构造函数有第三个 未记录的 参数 用于将自定义 HTTP 标头传递给连接请求 We
  • SignalR OnConnected 和 OnDisconnected 未触发

    我的集线器中的 OnConnected 和 OnDisconnected 覆盖无法触发 我遇到了问题 出于复制目的 我有一个非常简单的集线器 public class OnlineHub Hub public void TestMethod
  • 在 C# 中重复一个函数,直到它不再抛出异常

    我有一个调用 SOAP 接口并返回数据数组的类 但是 如果此请求超时 则会引发异常 这很好 但是 我希望我的程序尝试再次进行此调用 如果超时 我希望它继续拨打此电话 直到成功为止 我怎样才能做到这一点 例如 try salesOrdersA
  • 将组合框的 ItemsSource 设置为整数数组?

    将组合框的 ItemsSource 设置为整数数组
  • 使用反向一对一字段将 django 模型序列化为 JSON

    假设我有以下两个 django 1 3 模型 from django db import models class Patient models Model name models CharField Name max length 50
  • 在构造函数内注册事件?

    我一直在研究委托 事件和匿名方法 这样一来 有一点就变得非常清楚了 它不会简化在构造函数中注册任何事件方法或委托函数的过程吗 我的测试表明它是有效的 并且它可以防止您在实例化后必须声明它们 因为对象的构造函数会为您执行此操作 事实上 性能还
  • 如何检查程序是否已安装,如果没有则安装?

    由于完整性检查 我宁愿不使用 WMI 这是我所拥有的不起作用 tempdir Get Location tempdir tempdir tostring reg32 HKLM Software Microsoft Windows Curre
  • 解决元类冲突

    我需要创建一个根据某些条件使用不同基类的类 在一些课程中 我得到了臭名昭著的 TypeError metaclass conflict the metaclass of a derived class must be a non stric
  • 使用 ggplot2 绘制相关矩阵图

    我想创建一个相关矩阵图 即每个变量相对于其他变量绘制在散点图中的图 例如pairs or splom 我想用 ggplot2 来做到这一点 请参阅此处的示例 该链接提到了一些人为在 ggplot2 中执行此操作而编写的一些代码 但是 它已经
  • Java 中的类何时以及如何进行垃圾回收?

    我问了一个关于Java中垃圾收集的问题这个话题 但我得到的答案却给了我另一个问题 有人提到类也可以被垃圾收集器收集 这是真的 如果这是真的 这是如何运作的 当没有任何对象引用 Java 中的类时 它可能会被垃圾回收 在大多数简单的设置中 这
  • ruby 继承与 mixins

    在 Ruby 中 由于您可以包含多个 mixins 但只能扩展一个类 因此看起来 mixins 比继承更受青睐 我的问题 如果您正在编写必须扩展 包含才能有用的代码 为什么要把它变成一个类 或者换句话说 为什么不总是把它做成一个模块呢 我只
  • 将数组排序到索引数组指定的容器中的最有效方法?

    任务举例 data np array 1 2 3 4 5 6 7 8 9 idx np array 2 0 1 1 2 0 1 1 2 预期结果 binned np array 2 6 3 4 7 8 1 5 9 限制条件 应该很快 应该O