【问题标题】:Vectorize some data processing in numpy threshold analysis在 numpy 阈值分析中向量化一些数据处理
【发布时间】:2017-12-27 06:59:31
【问题描述】:

基本上我有一些带有维度(时间、纬度、经度)的网格化气象数据。

  1. 我需要遍历每个 gridsquare 的每个时间序列,确定连续天数 (“事件”)当变量高于阈值并将其存储到 一个新变量(THdays)
  2. 然后我查看新变量并找到超过一定持续时间的事件(THevents)

目前我有一个超级杂乱无章(非矢量化)的迭代,非常感谢您对如何加快这一进程的建议。谢谢!

import numpy as np
import itertools as it
##### Parameters
lg = 2000  # length to initialise array (must be long to store large number of events)
rl = 180  # e.g latitude
cl = 360  # longitude
pcts = [95, 97, 99] # percentiles which are the thresholds that will be compared
dt = [1,2,3] #duration thresholds, i.e. consecutive values (days) above threshold

##### Data
data   # this is the gridded data that is (time,lat,lon) , e.g. data = np.random.rand(1000,rl,cl)
# From this data calculate the percentiles at each gridsquare (lat/lon combination) which will act as our thresholds
histpcts = np.percentile(data, q=pcts, axis = 0)


##### Initialize arrays to store the results
THdays = np.ndarray((rl, cl, lg, len(pcts)), dtype='int16') #Array to store consecutive threshold timesteps
THevents = np.ndarray((rl,cl,lg,len(pcts),len(dt)),dtype='int16')

##### Start iteration to identify events
for p in range(len(pcts)):  # for each threshold value
    br = data>histpcts[p,:,:]  # Make boolean array where data is bigger than threshold

    # for every lat/lon combination
    for r,c in it.product(range(rl),range(cl)): 
        if br[:,r,c].any()==True: # This is to skip timeseries with nans only and so the iteration is skipped. Important to keep this or something that ignores an array of nans
            a = [ sum( 1 for _ in group ) for key, group in it.groupby( br[:,r,c] ) if key ] # Find the consecutive instances
            tm = np.full(lg-len(a), np.nan)   # create an array of nans to fill in the rest


            # Assign to new array
            THdays[r,c,0:len(a),p] = a  # Consecutive Thresholds days
            THdays[r,c,len(a):,p] = tm  # Fill the rest of array

            # Now cycle through and identify events 
            # (consecutive values) longer than a certain duration (dt)
            for d in range(len(dt)):
                b = THdays[r,c,THdays[r,c,:,p]>=dt[d],p]
                THevents[r,c,0:len(b),p,d] = b

【问题讨论】:

标签: python numpy vectorization


【解决方案1】:

你试过numba吗? 当您在 numpy 中使用简单的循环时,它将为您提供极大的加速。 您需要做的就是将您的代码放入一个函数中并应用装饰器@jit 来装饰函数。就是这样!!!

@jit
def myfun(inputs):
    ## crazy nested loops here

当然,您为 numba 提供的更多信息将获得更好的加速: 你可以在这里找到更多信息:http://numba.pydata.org/numba-doc/0.34.0/user/overview.html

【讨论】:

  • 如果你想获得最佳加速,你必须使用njit()而不是jit(),然后你必须处理一些限制。 OP 的代码不会神奇地转换为最佳代码。也许更快,但不是最佳的。
  • 我同意。但作为一种开始使用 numba jit 的方法更好。也因为 njit 的错误信息在你第一次偶然发现时很难解释。
  • 感谢@gioelelm 和@JohnZwinck,我尝试了jitnjit,然后停留在错误消息上。知道这意味着什么吗? raise patched_exception LoweringError: make_function(closure=None, code=<code object <genexpr> at 00000000180D87B0, file "<ipython-input-14-bfc99f64006d>", line 24>, name=None, defaults=None)
  • 并尝试重构一切以使用 numpy 数组(而不是列表)和 numpy 函数(例如 np.sum 而不是 sum)
猜你喜欢
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 2020-11-22
  • 2018-10-30
  • 1970-01-01
  • 2018-12-08
相关资源
最近更新 更多