Python 中海量 numpy 数组的内存高效排序

2024-04-14

我需要使用 numpy 对非常大的基因组数据集进行排序。我有一个 26 亿个浮点数的数组,维度 =(868940742, 3)加载后,它会占用我机器上大约 20GB 的内存。我有一台 2015 年初的 13 英寸 MacBook Pro,配备 16GB RAM、500GB 固态硬盘和 3.1 GHz intel i7 处理器。只是加载数组会溢出到虚拟内存,但不会到我的机器受到影响的程度,或者我必须停止我正在做的所有其他事情。

我从 22 个较小的数组一步步构建这个非常大的数组(N, 2)子数组。

功能FUN_1生成 2 个新的(N, 1)使用我称之为的 22 个子数组中的每一个的数组sub_arr.

第一个输出为FUN_1是通过插入值生成的sub_arr[:,0]在阵列上b = array([X, F(X)])第二个输出是通过放置生成的sub_arr[:, 0]使用数组放入 bin 中r = array([X, BIN(X)])。我称这些输出为b_arr and rate_arr, 分别。该函数返回一个 3 元组(N, 1) arrays:

import numpy as np

def FUN_1(sub_arr):
    """interpolate b values and rates based on position in sub_arr"""

    b = np.load(bfile)
    r = np.load(rfile)

    b_arr = np.interp(sub_arr[:,0], b[:,0], b[:,1])
    rate_arr = np.searchsorted(r[:,0], sub_arr[:,0])  # HUGE efficiency gain over np.digitize...

    return r[rate_r, 1], b_arr, sub_arr[:,1] 

我在 for 循环中调用该函数 22 次,并填充预先分配的零数组full_arr = numpy.zeros([868940742, 3])与价值观:

full_arr[:,0], full_arr[:,1], full_arr[:,2] = FUN_1

就这一步节省内存而言,我认为这是我能做的最好的事情,但我愿意接受建议。不管怎样,到目前为止我都没有遇到问题,而且只需要大约 2 分钟。

这是排序例程(有两个连续排序)

for idx in range(2):
    sort_idx = numpy.argsort(full_arr[:,idx])
    full_arr = full_arr[sort_idx]
    # ...
    # <additional processing, return small (1000, 3) array of stats>

现在这种方法已经开始工作了,尽管速度很慢(大约需要 10 分钟)。然而,我最近开始使用更大、更精细的分辨率表[X, F(X)]上述插值步骤的值FUN_1返回b_arr现在排序确实变慢了,尽管其他一切都保持不变。

有趣的是,我什至没有在排序现在滞后的步骤中对插值进行排序。以下是不同插值文件的一些片段 - 较小的插值文件在每种情况下大约小 30%,并且就第二列中的值而言更加统一;较慢的具有更高的分辨率和更多的独特值,因此插值的结果可能更独特,但我不确定这是否会产生任何影响......?

更大、更慢的文件:

17399307    99.4
17493652    98.8
17570460    98.2
17575180    97.6
17577127    97
17578255    96.4
17580576    95.8
17583028    95.2
17583699    94.6
17584172    94

更小、更统一的常规文件:

1       24  
1001    24  
2001    24  
3001    24  
4001    24  
5001    24
6001    24
7001    24

我不确定是什么导致了这个问题,我对任何建议或关于在这种类型的内存限制情况下进行排序的一般输入感兴趣!


目前每次致电np.argsort正在生成一个(868940742, 1)int64 索引数组,它本身就占用约 7 GB。此外,当您使用这些索引对列进行排序时full_arr你正在生成另一个(868940742, 1)浮点数组,因为花式索引总是返回副本而不是视图 http://docs.scipy.org/doc/numpy/user/basics.indexing.html#index-arrays.

一个相当明显的改进是排序full_arr使用其到位.sort() method http://docs.scipy.org/doc/numpy/reference/generated/numpy.sort.html。很遗憾,.sort()不允许您直接指定要排序的行或列。然而,你can指定结构化数组的排序依据字段。因此,您可以通过获取一个值来强制对三列之一进行就地排序view http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.view.html作为具有三个浮点字段的结构化数组添加到数组上,然后按以下字段之一进行排序:

full_arr.view('f8, f8, f8').sort(order=['f0'], axis=0)

在这种情况下我正在排序full_arr位于第 0 个字段,对应于第一列。请注意,我假设有三个 float64 列('f8') - 如果您的数据类型不同,您应该相应地更改它。这还要求您的数组是连续的并且采用行优先格式,即full_arr.flags.C_CONTIGUOUS == True.

这种方法的功劳应该归功于 Joe Kington 的回答here https://stackoverflow.com/a/2828371/1461210.


虽然它需要更少的内存,但不幸的是,与使用相比,按字段对结构化数组进行排序要慢得多np.argsort生成索引数组,正如您在下面的评论中提到的那样(请参阅上一个问题 https://stackoverflow.com/q/19682521/1461210)。如果你使用np.argsort要获取一组索引进行排序,您可能会通过使用获得适度的性能增益np.take而不是直接索引来获取排序数组:

 %%timeit -n 1 -r 100 x = np.random.randn(10000, 2); idx = x[:, 0].argsort()
x[idx]
# 1 loops, best of 100: 148 µs per loop

 %%timeit -n 1 -r 100 x = np.random.randn(10000, 2); idx = x[:, 0].argsort()
np.take(x, idx, axis=0)
# 1 loops, best of 100: 42.9 µs per loop

但是,我不希望在内存使用方面看到任何差异,因为两种方法都会生成副本。


关于为什么对第二个数组进行排序更快的问题 - 是的,当数组中唯一值较少时,您应该期望任何合理的排序算法都会更快,因为平均而言,它要做的工作较少。假设我有一个 1 到 10 之间的随机数字序列:

5  1  4  8  10  2  6  9  7  3

有10个! = 3628800 种可能的排列这些数字的方式,但只有一种是按升序排列的。现在假设只有 5 个唯一数字:

4  4  3  2  3  1  2  5  1  5

现在有 2⁵ = 32 种方法可以按升序排列这些数字,因为我可以交换排序向量中的任何一对相同的数字而不会破坏顺序。

默认情况下,np.ndarray.sort() uses 快速排序 https://en.wikipedia.org/wiki/Quicksort. The qsort https://en.wikipedia.org/wiki/Quicksort#Repeated_elements该算法的变体通过递归地选择数组中的“枢轴”元素,然后对数组重新排序,使得所有小于枢轴值的元素都放置在它之前,所有大于枢轴值的元素都放置在它之后。等于主元的值已经排序。具有较少的唯一值意味着,平均而言,在任何给定的扫描中,更多的值将等于主元值,因此需要更少的扫描来对数组进行完全排序。

例如:

%%timeit -n 1 -r 100 x = np.random.random_integers(0, 10, 100000)
x.sort()
# 1 loops, best of 100: 2.3 ms per loop

%%timeit -n 1 -r 100 x = np.random.random_integers(0, 1000, 100000)
x.sort()
# 1 loops, best of 100: 4.62 ms per loop

在此示例中,两个数组的数据类型相同。如果较小的数组与较大的数组相比具有较小的项目大小,那么由于花哨的索引而复制它的成本也会较小。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 中海量 numpy 数组的内存高效排序 的相关文章

  • 键入的完整命令行

    我想获得输入时的完整命令行 This join sys argv 在这里不起作用 删除双引号 另外 我不想重新加入已解析和拆分的内容 有任何想法吗 你太迟了 当键入的命令到达 Python 时 您的 shell 已经发挥了它的魔力 例如 引
  • Keras model.predict 函数给出输入形状错误

    我已经在 Tensorflow 中实现了通用句子编码器 现在我正在尝试预测句子的类概率 我也将字符串转换为数组 Code if model model type universal classifier basic class probs
  • 使用 NumPy 编写一个函数来计算具有特定公差的积分

    我想编写一个自定义函数来以特定容差对表达式 python 或 lambda 函数 进行数字积分 我知道与scipy integrate quad人们可以简单地改变epsabs但我想使用 numpy 自己编写该函数 From 这篇博文 htt
  • 如何在Windows中的Python 3.9下pip安装pickle?

    我需要pickle https docs python org 3 9 library pickle html module pickle包安装在我的下面Python 3 9在 Windows 10 下 我尝试过的 当尝试与pip inst
  • 用 Python 绘制直方图

    我有两个列表 x 和 y x 包含字母表 A Z Y 包含它们在文件中的频率 我尝试研究如何在直方图中绘制这些值 但在理解如何绘制它方面没有成功 n bins patches plt hist x 26 normed 1 facecolor
  • Swift 使用哪种通用排序算法?它在排序数据上表现不佳

    我一直在挑选和探索 Swift 标准库sort 其函数为Array类型 令我惊讶的是 我注意到它在已经排序的数据上表现不佳 对数组进行排序Int打乱顺序似乎比对已经排序的同一个数组进行排序快 5 倍 对已打乱顺序的对象数组进行排序比对已按排
  • Django 多对多关系(类别)

    我的目标是向我的 Post 模型添加类别 我希望以后能够按不同类别 有时是多个类别 查询所有帖子 模型 py class Category models Model categories 1 red 2 blue 3 black title
  • 在 Linux 上使用多处理时,TKinter 窗口不会出现

    我想生成另一个进程来异步显示错误消息 同时应用程序的其余部分继续 我正在使用multiprocessingPython 2 6 中的模块来创建进程 我试图用以下命令显示窗口TKinter 这段代码在Windows上运行良好 但在Linux上
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • 为什么将模块级代码放入函数中然后调用该函数在Python中速度更快?

    在亚历克斯 马尔泰利的回应中使 Python 脚本面向对象 https stackoverflow com questions 1813117 making a python script object oriented 他提到在 Pyth
  • Python 属性和 Swig

    我正在尝试使用 swig 为一些 C 代码创建 python 绑定 我似乎遇到了一个问题 试图从我拥有的一些访问器函数创建 python 属性 方法如下 class Player public void entity Entity enti
  • Django 2、python 3.4 无法解码 urlsafe_base64_decode(uidb64)

    我正在尝试通过电子邮件激活用户 电子邮件有效 编码有效 我使用了 django1 11 中的方法 该方法运行成功 在 Django 1 11 中 以下内容成功解码为 28 其中 uidb64 b Mjg force text urlsafe
  • 为什么 Collections.counter 这么慢?

    我正在尝试解决罗莎琳德的基本问题 即计算给定序列中的核苷酸 并在列表中返回结果 对于那些不熟悉生物信息学的人来说 它只是计算字符串中 4 个不同字符 A C G T 出现的次数 我期望collections Counter是最快的方法 首先
  • 是否可以在Python中将日+月(不是年)与当前日+月进行比较?

    我正在获取 5 月 10 日 格式的数据 我试图弄清楚它是今年还是明年 该日期仅一年 因此 5 月 10 日表示 2015 年 5 月 10 日 而 5 月 20 日表示 2014 年 5 月 20 日 为此 我想将字符串转换为日期格式并进
  • 如何按 pandas 中的值对系列进行分组?

    我现在有一只熊猫Series与数据类型Timestamp 我想按日期对其进行分组 并且每组中有许多行具有不同的时间 看似显而易见的方法类似于 grouped s groupby lambda x x date 然而 熊猫的groupby按索
  • 如何在matplotlib中调整x轴

    I have a graph like this x轴上的数据表示小时 所以我希望x轴设置为0 24 48 72 而不是现在的值 很难看到 0 100 之间的数据 fig1 plt figure ax fig1 add subplot 11
  • 如何通过 Python Requests 库使用基本 HTTP 身份验证?

    我正在尝试在 Python 中使用基本的 HTTP 身份验证 我正在使用Requests https docs python requests org 图书馆 auth requests post http hostname auth HT
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • 两种 ODE 求解器之间的差异

    我想知道 两者之间有什么区别ODEINT and solve ivp用于求解微分方程 它们之间有什么优点和缺点 f1 solve ivp f 0 1 y0 y0 is the initial point f2 odeint f y0 0 1
  • 使用 pandas 单元格中列表的长度选择行[重复]

    这个问题在这里已经有答案了 我有一张表 df a b c 1 x y x 2 x z c d 3 x t e f g 只是想知道如何使用 c 列的长度选择行 such as df loc len df c gt 1 我知道这是不对的 正确的

随机推荐

  • 一瞥让一切都慢了 50 倍

    我一直在使用glimpse来尝试解决一些页面速度慢的问题 结果发现glipse就是原因 页面请求超过 30000 秒 毫不夸张地说它们是即时的 所以我一直在追鬼 当导致如此速度差异时 我如何使用一瞥来查看一切需要多长时间 我是否配置错误或者
  • 如何在 iPad 硬件中(而不是在模拟器中)测试 iPad 应用程序

    在 iPad 模拟器上完成构建和测试后 我需要在 iPad 硬件上测试该应用程序 我怎样才能做到这一点 如果您已支付开发人员密钥的费用 则应该能够打开管理器窗口 设置您的设备 然后选择设备而不是模拟器作为 XCode 中的目标 看苹果的文档
  • 更高效的 matplotlib 堆积条形图 - 如何计算底部值

    我需要一些帮助 使用 matlibplot 在 python 中制作一组堆积条形图 我的基本代码如下 但我的问题是如何生成值bottom对于第二个之外的任何元素有效率的 我可以让示例图正确堆叠 始终从下到上为 a b c d import
  • 我应该在 OBDII 的 BLE IOS 设备中使用什么 BLE 特性

    您好 我想知道我应该从这个 OBDII BLE 设备 加密狗中使用什么写入和通知特性 我想在 Flutter 中创建一个适用于 IOS 的程序 有不少 Device name VEEPEAK Device id 34E2B2AF 60F4
  • 更改值结转次数的 maxgap

    我有一个类似于以下内容的数据框 library data table test lt data table data frame value c 5 NA 8 NA NA 8 6 NA NA 10 locf N c 1 NA 1 NA NA
  • google.script.run.withSuccessHandler() 返回未定义

    我使用下面提供的代码在单独的 GS 文件中创建了一个数组 我尝试在 HTML 文件中调用它 我的目标是将数组的内容与参数进行比较email 但是 返回的值google script run withSuccessHandler is und
  • 来自浏览器的带有正文的异步 GET 请求

    好吧 我知道这是一个坏主意 不应该这样做 但为了这个问题 请假设没有其他方法 我得到的 API 端点需要以空对象作为主体的 GET 请求 有没有办法从浏览器执行异步请求 我在用着axios使用的库XMLHttpRequest在引擎盖下和MD
  • 如何在Qt中暂时断开与插槽的信号?

    我用信号连接一个插槽 但现在我想暂时断开它们的连接 这是我的班级声明的一部分 class frmMain public QWidget private QTimer myReadTimer private slots void on btn
  • POST 请求(Javascript)

    如何在 Javascript 中发出简单的 POST 请求而不使用表单且不回发 虽然我从 sundeep 答案中获取代码示例 但为了完整性而将代码发布在此处 var url sample url php var params lorem i
  • 如何在 Django 1.8 中使用 jinja2 作为模板引擎

    我一直在研究如何在 django 1 8 中使用 jinja2 但是没有将 django 与 jinja2 一起使用的完整源代码 我想知道你们是否知道在 django 中使用 jinja2 的过程 我查看了官方文档并查看了以下问题 如何设置
  • 按 Option 键隐藏/显示应用程序主菜单中的菜单项

    我想在应用程序的主菜单中添加一个很少使用的菜单项 我希望它默认隐藏 仅当用户按住 Option 键时才显示 我该怎么做呢 看来我应该处理flagsChanged 但它是NSResponder的方法和NSMenu不继承自NSResponder
  • 为什么使用 boost 后 C++ 比 python 快得多?

    我的目标是用 Python 编写一个用于频谱有限元的小型库 为此我尝试使用 Boost 通过 C 库扩展 Python 希望它能让我的代码更快 class Quad public Quad int int double integrate
  • 将 TDD 与 Web 应用程序开发集成的最佳实践? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 单元测试和 ASP NET Web 应用程序在我的团队中是一个模棱两可的点 通常情况下 良好的测试实践会被忽视 Web 应用程序最终会在没有测试
  • 如何对库进行临时签名?

    尝试运行链接到动态库的可执行文件 出现以下错误 Library not loaded Reason tried
  • 为什么小于不起作用?

    这看起来很简单 但为什么这种比较不起作用呢 if nmax lt num nmax num 我把它放在一个循环中 寻找最大的数字 第一个数字是105 然后是89 然后是99 然后是一大堆大于99的数字 第一个数字是要测试的数字 第二个数字是
  • GWT:对RichTextArea进行文本限制并阻止用户输入更多字符

    我正在使用 GWT RixhText Area 并希望在 richText Area 中限制 100 个字符 现在我正在做这个 description addKeyDownHandler new KeyDownHandler Overrid
  • Elastic Beanstalk 剥离 Sec-WebSocket-Accept 标头

    我正在尝试让 NET Core 应用程序在 elastic beanstalk 上运行 以从浏览器中的 javascript 接收 websockets 连接 当我在本地计算机上测试 AWS 之外的客户端和服务器时 我能够在两者之间建立 W
  • 数据流:将 Top 模块与 Python SDK 结合使用:单元素 PCollection

    我正在查看 incubator beam 存储库上的 word counting py 示例 从数据流文档链接 我想修改它以获得n 出现次数最多的 这是我的管道 counts lines split gt gt beam ParDo Wor
  • Java中如何初始化日期类型变量?

    import java util Date Date firstDate 我不知道如何初始化firstDate例如对于你说的字符串 String line1 First line 但是日期的格式是什么 你能给我一个例子吗 以下是 Oracl
  • Python 中海量 numpy 数组的内存高效排序

    我需要使用 numpy 对非常大的基因组数据集进行排序 我有一个 26 亿个浮点数的数组 维度 868940742 3 加载后 它会占用我机器上大约 20GB 的内存 我有一台 2015 年初的 13 英寸 MacBook Pro 配备 1