首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >改进最小/最大下采样

改进最小/最大下采样
EN

Stack Overflow用户
提问于 2019-01-30 13:14:01
回答 4查看 2.5K关注 0票数 7

我有一些大数组(大约1亿点),我需要交互绘制。我正在使用Matplotlib。绘制数组的速度非常慢,这是一种浪费,因为无论如何你都无法想象出这么多的点。

所以我做了一个min/max抽取函数,我把它绑定到轴的'xlim_changed‘回调。我采用了一种min/max方法,因为数据包含快速的尖峰,我不希望仅仅通过遍历数据就错过它。有更多的包装到x-限制,并在某些条件下跳过处理,但相关部分如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def min_max_downsample(x,y,num_bins):
    """ Break the data into num_bins and returns min/max for each bin"""
    pts_per_bin = x.size // num_bins    

    #Create temp to hold the reshaped & slightly cropped y
    y_temp = y[:num_bins*pts_per_bin].reshape((num_bins, pts_per_bin))
    y_out      = np.empty((num_bins,2))
    #Take the min/max by rows.
    y_out[:,0] = y_temp.max(axis=1)
    y_out[:,1] = y_temp.min(axis=1)
    y_out = y_out.ravel()

    #This duplicates the x-value for each min/max y-pair
    x_out = np.empty((num_bins,2))
    x_out[:] = x[:num_bins*pts_per_bin:pts_per_bin,np.newaxis]
    x_out = x_out.ravel()
    return x_out, y_out

这是相当好的工作,是足够快(~80毫秒在1e8点& 2k仓)。延迟非常小,因为它定期重新计算和更新行的x&y数据。

然而,我唯一的抱怨是在x数据中。此代码重复每个bin的左边沿的x值,并且不返回y min/max对的真正x位置。我通常将回收箱的数量设置为轴像素宽度的两倍。所以你看不出有什么区别,因为垃圾箱是如此的small...but,我知道它在那里.这让我心烦。

所以,尝试2号,它返回每分钟/最大对的实际x值。然而,它大约慢了5倍。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def min_max_downsample_v2(x,y,num_bins):
    pts_per_bin = x.size // num_bins
    #Create temp to hold the reshaped & slightly cropped y
    y_temp = y[:num_bins*pts_per_bin].reshape((num_bins, pts_per_bin))
    #use argmax/min to get column locations
    cc_max = y_temp.argmax(axis=1)
    cc_min = y_temp.argmin(axis=1)    
    rr = np.arange(0,num_bins)
    #compute the flat index to where these are
    flat_max = cc_max + rr*pts_per_bin
    flat_min = cc_min + rr*pts_per_bin
    #Create a boolean mask of these locations
    mm_mask  = np.full((x.size,), False)
    mm_mask[flat_max] = True
    mm_mask[flat_min] = True  
    x_out = x[mm_mask]    
    y_out = y[mm_mask]  
    return x_out, y_out

这大约需要400+ ms在我的机器上,这变得相当引人注目。所以,我的问题是,是否有一条路可以走得更快,并提供同样的结果?瓶颈主要集中在numpy.argminnumpy.argmax函数中,它们比numpy.minnumpy.max慢一些。

答案可能是使用#1版本,因为它在视觉上并不重要。或者尝试加快速度,比如cython (我从未使用过)。

FYI在Windows上使用Python 3.6.4。示例用法如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
x_big = np.linspace(0,10,100000000)
y_big = np.cos(x_big )
x_small, y_small = min_max_downsample(x_big ,y_big ,2000) #Fast but not exactly correct.
x_small, y_small = min_max_downsample_v2(x_big ,y_big ,2000) #correct but not exactly fast.
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-01-31 06:28:57

我通过直接使用arg(min|max)的输出来索引数据数组,从而获得了更好的性能。这是以额外调用np.sort为代价的,但是要排序的轴只有两个元素( min )。/最大。(索引)和整个数组相当小(回收箱的数量):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def min_max_downsample_v3(x, y, num_bins):
    pts_per_bin = x.size // num_bins

    x_view = x[:pts_per_bin*num_bins].reshape(num_bins, pts_per_bin)
    y_view = y[:pts_per_bin*num_bins].reshape(num_bins, pts_per_bin)
    i_min = np.argmin(y_view, axis=1)
    i_max = np.argmax(y_view, axis=1)

    r_index = np.repeat(np.arange(num_bins), 2)
    c_index = np.sort(np.stack((i_min, i_max), axis=1)).ravel()

    return x_view[r_index, c_index], y_view[r_index, c_index]

我检查了你的例子的时间,我得到了:

  • min_max_downsample_v1:110 ms±5 ms
  • min_max_downsample_v2:240 ms±8.01 ms
  • min_max_downsample_v3:164 ms±1.23 ms

我还检查了对arg(min|max)的调用后直接返回,结果是相同的164 ms,即不再有真正的开销。

票数 3
EN

Stack Overflow用户

发布于 2019-01-31 15:48:16

因此,这并不能解决加速特定函数的问题,但它确实展示了一些方法,可以有效地绘制出大量点的直线。这假设x点是有序的,并且是一致的(或接近一致的)采样。

设置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from pylab import *

这是一个我喜欢的函数,它通过在每个间隔中随机选择一个来减少点数。它不能保证显示数据中的每个峰值,但它没有直接抽取数据那么多问题,而且速度很快。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def calc_rand(y, factor):
    split = y[:len(y)//factor*factor].reshape(-1, factor)
    idx = randint(0, split.shape[-1], split.shape[0])
    return split[arange(split.shape[0]), idx]

这是看信号信封的最小值和最大值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def calc_env(y, factor):
    """
    y : 1D signal
    factor : amount to reduce y by (actually returns twice this for min and max)
    Calculate envelope (interleaved min and max points) for y
    """
    split = y[:len(y)//factor*factor].reshape(-1, factor)
    upper = split.max(axis=-1)
    lower = split.min(axis=-1)
    return c_[upper, lower].flatten()

下面的函数可以接受这两种方法之一,并使用它们来减少绘制的数据。在默认情况下,实际获取的点数是5000,这应该远远超过监视器的分辨率。数据在减少后被缓存。内存可能是一个问题,特别是大量的数据,但不应该超过原始信号所需的数量。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def plot_bigly(x, y, *, ax=None, M=5000, red=calc_env, **kwargs):
    """
    x : the x data
    y : the y data
    ax : axis to plot on
    M : The maximum number of line points to display at any given time
    kwargs : passed to line
    """
    assert x.shape == y.shape, "x and y data must have same shape!"
    if ax is None:
        ax = gca()

    cached = {}

    # Setup line to be drawn beforehand, note this doesn't increment line properties so
    #  style needs to be passed in explicitly
    line = plt.Line2D([],[], **kwargs)
    def update(xmin, xmax):
        """
        Update line data

        precomputes and caches entire line at each level, so initial
        display may be slow but panning and zooming should speed up after that
        """
        # Find nearest power of two as a factor to downsample by
        imin = max(np.searchsorted(x, xmin)-1, 0)
        imax = min(np.searchsorted(x, xmax) + 1, y.shape[0])
        L = imax - imin + 1
        factor = max(2**int(round(np.log(L/M) / np.log(2))), 1)

        # only calculate reduction if it hasn't been cached, do reduction using nearest cached version if possible
        if factor not in cached:
            cached[factor] = red(y, factor=factor)

        ## Make sure lengths match correctly here, by ensuring at least
        #   "factor" points for each x point, then matching y length
        #  this assumes x has uniform sample spacing - but could be modified
        newx = x[imin:imin + ((imax-imin)//factor)* factor:factor]
        start = imin//factor
        newy = cached[factor][start:start + newx.shape[-1]]
        assert newx.shape == newy.shape, "decimation error {}/{}!".format(newx.shape, newy.shape)

        ## Update line data
        line.set_xdata(newx)
        line.set_ydata(newy)

    update(x[0], x[-1])
    ax.add_line(line)
    ## Manually update limits of axis, as adding line doesn't do this
    #   if drawing multiple lines this can quickly slow things down, and some
    #   sort of check should be included to prevent unnecessary changes in limits
    #   when a line is first drawn.
    ax.set_xlim(min(ax.get_xlim()[0], x[0]), max(ax.get_xlim()[1], x[1]))
    ax.set_ylim(min(ax.get_ylim()[0], np.min(y)), max(ax.get_ylim()[1], np.max(y)))

    def callback(*ignore):
        lims = ax.get_xlim()
        update(*lims)

    ax.callbacks.connect('xlim_changed', callback)

    return [line]

这是一些测试代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
L=int(100e6)
x=linspace(0,1,L)
y=0.1*randn(L)+sin(2*pi*18*x)
plot_bigly(x,y, red=calc_env)

在我的机器上这个显示得非常快。缩放有一点滞后,特别是当它大幅度的时候。潘宁没有问题。使用随机选择,而不是最小和最大是相当快,并只有问题,在非常高的缩放水平。

票数 2
EN

Stack Overflow用户

发布于 2019-01-31 19:02:58

编辑:将parallel=True添加到numba ..。更快的

最后,我将argmin+max例程与@a_来宾的答案和链接到这个相关的同时最小最大值问题的改进索引进行了混合。

这个版本为每个min/max y对返回正确的x值,感谢numba,它实际上比“快速但不完全正确”的版本要快一些。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from numba import jit, prange
@jit(parallel=True)
def min_max_downsample_v4(x, y, num_bins):
    pts_per_bin = x.size // num_bins
    x_view = x[:pts_per_bin*num_bins].reshape(num_bins, pts_per_bin)
    y_view = y[:pts_per_bin*num_bins].reshape(num_bins, pts_per_bin)    
    i_min = np.zeros(num_bins,dtype='int64')
    i_max = np.zeros(num_bins,dtype='int64')

    for r in prange(num_bins):
        min_val = y_view[r,0]
        max_val = y_view[r,0]
        for c in range(pts_per_bin):
            if y_view[r,c] < min_val:
                min_val = y_view[r,c]
                i_min[r] = c
            elif y_view[r,c] > max_val:
                max_val = y_view[r,c]
                i_max[r] = c                
    r_index = np.repeat(np.arange(num_bins), 2)
    c_index = np.sort(np.stack((i_min, i_max), axis=1)).ravel()        
    return x_view[r_index, c_index], y_view[r_index, c_index]

使用timeit对速度进行比较显示,numba代码大约快2.6倍,并且提供了比v1更好的结果。它比numpy的argmin & argmax系列快10倍多一点。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
%timeit min_max_downsample_v1(x_big ,y_big ,2000)
96 ms ± 2.46 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit min_max_downsample_v2(x_big ,y_big ,2000)
507 ms ± 4.75 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit min_max_downsample_v3(x_big ,y_big ,2000)
365 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit min_max_downsample_v4(x_big ,y_big ,2000)
36.2 ms ± 487 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54449631

复制
相关文章
Omnibus GitLab 使用说明
本文介绍了如何使用 Omnibus GitLab 进行部署和配置 GitLab,包括安装、配置、数据存储和邮件服务等方面的内容。
shaonbean
2018/01/02
1.3K0
gitlab升级(Omnibus packages)
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el6/gitlab-ce-8.7.0-ce.0.el6.x86_64.rpm
donghui
2019/04/19
8010
Gitlab-ci 构建
原因:服务端证书有问题。我使用的是自建的gitlab服务器,服务器上的证书差了一个属性。打印出来需要包含如下属性:
天地一小儒
2022/12/28
5350
omnibus-gitlab迁移记录 原
sudo scp 1462837514_gitlab_backup.tar root@x.x.x.x:/var/opt/gitlab/backups
donghui
2019/04/19
1.3K0
Gitlab-CI 中的 Pip 缓存的设置
最近给实验室的Gitlab服务器开启了CI功能,采用的是docker模式,每次都启动一个全新的镜像进行构建。
DevOps时代
2019/10/06
2.3K0
Gitlab-ci:从零开始的前端自动化部署
(1) 通过在项目根目录下配置**.gitlab-ci.yml**文件,可以控制ci流程的不同阶段,例如install/检查/编译/部署服务器。gitlab平台会扫描.gitlab-ci.yml文件,并据此处理ci流程
Nealyang
2020/09/01
1.9K0
Kubernetes 集群中运行 GitLab-Runner 来执行 GitLab-CI
GitLab-CI 是一套 GitLab 提供给用户使用的持续集成系统,GitLab 8.0 版本以后是默认集成并且默认启用。GitLab-Runner 是配合 GitLab-CI 进行使用的,GitLab 里面每个工程都会定义一些该工程的持续集成脚本,该脚本可配置一个或多个 Stage 例如构建、编译、检测、测试、部署等等。当工程有代码更新时,GitLab 会自动触发 GitLab-CI,此时 CitLab-CI 会找到事先注册好的 GitLab-Runner 通知并触发该 Runner 来执行预先定义好的脚本。
kubernetes中文社区
2019/06/24
2.8K0
Kubernetes 集群中运行 GitLab-Runner 来执行 GitLab-CI
Kubernetes 集群中运行 GitLab-Runner 来执行 GitLab-CI
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aixiaoyang168/article/details/81149264
哎_小羊
2019/05/25
3.1K0
如何利用Gitlab-CI持续部署到远程机器?
如果看过《基于docker-compose的Gitlab CI/CD实践&排坑指南》这篇文章的朋友,会注意到我是在 Gitlab-Runner服务器上自动部署的站点,本次我们结合ssh部署到远程机器(将CI服务器和部署服务器分离,避免资源抢占)。
有态度的马甲
2020/07/29
2.4K0
如何利用Gitlab-CI持续部署到远程机器?
gitlab-ci 配置复用 - reference tags
在 GitLab 13.9 中增加了一个新的关键字 !reference。这个关键字可以在任意位置复用已存在的配置。
老麦
2022/12/24
8660
gitlab-ci 配置复用 - reference tags
使用 vagrant 从搭建 gitlab server 开始体验整个 gitlab CI/CD 过程
GitLab一个开源的git仓库管理平台,方便团队协作开发、管理。在GitLab上可以实现完整的CI(持续集成)、CD(持续发布)流程。而且还提供了免费使用的Plan,以及免费的可以独立部署的社区版本。
用户7685359
2020/08/22
1K0
原 记在解决GitLab-CI下的Dock
问题描述 最近一直在测试GitLab下的Runner,并在其下实现CI,其中遇到Docker Image编译后推送到Gitlab的容器中心失败的问题. gitlab-ci.yml Runner 配置 在容器内执行完Docker镜像的编译后,自动推送到注册中心时,报如下错误: c2bf021f0c8d: Layer already exists cd7100a72410: Layer already exists dcf1253999b2: Pushed a7e843cd55f6: Pushed 4fef4e
霡霂
2018/06/04
1.3K0
Gitlab 从 12.1 版本开始不再支持 MySQL
Gitlab 官方 宣布 ,将从 12.1 版本开始不再支持 MySQL 数据库。早在 2017 年 7 月,Gitlab 就计划将弃用对 MySQL 的支持。而目前这个决定将从 12.1 版本开始。
Debian中国
2020/01/21
9890
Gitlab安装使用及汉化配置
一、GitLab简介 GitHub是2008年由Ruby on Rails编写而成,与业界闻名的Github类似;但要将代码上传到GitHub上面,而且将项目设为私有还要收费。GitLab 是一个用于
shaonbean
2018/01/02
6.3K0
玩转CVM:Gitlab安装搭建
本教程将讲解如何依托腾讯云主机(CVM),以Docker方式搭建Gitlab服务。具体将包括:Docker安装,Gitlab安装与配置,Gitlab的开发流程示例,以及基于Gitlab的持续集成(CI/CD)的介绍。
溪歪歪
2019/07/07
8.6K0
K8S容器环境下GitLab-CI和GItLab Runner 部署记录
注意:本示例部署所涉及到的image镜像均导入到Harbor私有私仓(172.16.60.230) 。
洗尽了浮华
2021/04/01
7.6K0
K8S容器环境下GitLab-CI和GItLab Runner 部署记录
SonarQube 之 gitlab-plugin 配合 gitlab-ci 完成每次 commit 代码检测
哎_小羊
2018/01/02
9.3K2
SonarQube 之 gitlab-plugin 配合 gitlab-ci 完成每次 commit 代码检测
『中级篇』docker之CI/CD持续集成-(终结篇)(77)
PS:学习这个技术一定要紧随时代的潮流,干IT没办法,逆水行舟不进则退!不断的追随docker的新技术,学习的东西一定要实践,最好在工作中,只有这样才能提高咱们自己的水平,遇到的问题多在 https://stackoverflow.com/ 进行查看大神们的解决方案,国内baidu太坑了,记住你遇到的问题可能很多时候都是小问题,小细节。还有一点是https://github.com上多看docker的源码。多提issue,有热心的人会帮咱们进行解答的。推荐使用https://google.com,自己解决问题。科学上网也是搞IT必须的。中级篇也就终结了,后面也会退出高级篇,希望各位老铁,学习愉快,工作顺利,少踩坑! 谢谢您一如既往的关注和支持我,后续高级篇继续相见!跪安了!
IT架构圈
2018/10/13
1.5K0
『中级篇』docker之CI/CD持续集成-(终结篇)(77)
用Gitlab玩CI/CD
持续集成(CONTINUOUS INTEGRATION)是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。
李俊鹏
2021/02/23
1.4K0
用Gitlab玩CI/CD
点击加载更多

相似问题

GitLab/GitLab-CI Omnibus包配置sidekiq并发

31

Gitlab Omnibus 7.8.0上gitlab-ci的配置

12

如何在Gitlab Omnibus中检查GO版本

244

gitlab-ci多java版本

130

如何更改Gitlab的8080端口(CE - Omnibus版本)?

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文