Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 正在寻找在3600x20x20的xarray中查找阈值之间的值的最快方法_Python_Python Xarray - Fatal编程技术网

Python 正在寻找在3600x20x20的xarray中查找阈值之间的值的最快方法

Python 正在寻找在3600x20x20的xarray中查找阈值之间的值的最快方法,python,python-xarray,Python,Python Xarray,我想计算平均温度介于两个值(比如293K和303K)之间的天数。这需要针对大约10000x20x20的大型阵列(时间、纬度、经度)进行计算。在这种规模下,代码的效率成为一个问题。我知道循环效率很低,但我还没有想到另一种编码方法 简而言之,我正在寻找一段比我在下面插入的代码更有效的代码。欢迎任何提示或参考 (除上述内容外,我对python还是一个新手,因此我们将非常感谢您提供的任何反馈!) 首先,我有三个嵌套循环(对于I。对于j。对于k),但这花费了大约100倍的时间。使用1*(布尔值)证明更有效

我想计算平均温度介于两个值(比如293K和303K)之间的天数。这需要针对大约10000x20x20的大型阵列(时间、纬度、经度)进行计算。在这种规模下,代码的效率成为一个问题。我知道循环效率很低,但我还没有想到另一种编码方法

简而言之,我正在寻找一段比我在下面插入的代码更有效的代码。欢迎任何提示或参考

(除上述内容外,我对python还是一个新手,因此我们将非常感谢您提供的任何反馈!)

首先,我有三个嵌套循环(
对于I
对于j
对于k
),但这花费了大约100倍的时间。使用
1*(布尔值)
证明更有效。我现在正试图摆脱我的最后一个循环(
for I
)。速度非常重要,因为此脚本将包含在交互式web应用程序中

将xarray作为xr导入
将numpy作为np导入
导入时间
#首先构造一个维度为纬度、经度和时间的温度数据数组
da_t1=xr.DataArray([[290295300305295],
[295, 295, 305, 295, 290],
[300, 300, 300, 305, 295],
[290, 295, 300, 305, 295],
[290, 295, 300, 305, 295]],
dims=['lat','lon'],
坐标={'lat':[-5,-2.5,0,2.5,5],'lon':[33,35,37,39,41]})
da_t2=xr.DataArray([[295295305295295295],
[295, 295, 305, 295, 290],
[300, 300, 300, 305, 295],
[290, 300, 300, 305, 305],
[290, 285, 285, 285, 295]],
dims=['lat','lon'],
坐标={'lat':[-5,-2.5,0,2.5,5],'lon':[33,35,37,39,41]})
da=xr.concat([da_t1,da_t2],“时间”)
#创建一个零数组,以跟踪每个单元格在特定温度范围内的天数
零=da[0]
零点值=np零点((da.sizes['lat'],da.sizes['lon']))
#循环遍历时间步长和单元格,以计算每个单元格在温度范围内的天数
交易额=(293303)
#这是可以使用更快性能的部分
开始=时间。时间()
对于范围(0,(len(da.time))内的i:

int_array=1*(da.values[i]>=trange[0])*(da.values[i]只需使用元素级布尔/逻辑索引,如

in_between = np.logical_and(da.values[i] >= trange[0], da.values[i] <= trange[1])

sum_in_between = np.count_nonzero(in_between) # True = 1, False = 0
in\u between=np.logical\u和(da.values[i]>=trange[0],da.values[i]我的方法是

((da >= trange[0]) & (da <= trange[1])).sum(axis=0)

感谢您的回复!我正在寻找类似的内容,但是每个索引的总和。
sum\u in\u between
返回所有单元格/元素组合范围内的天数。请查看axis关键字np.count\u zero,以及np.bincount,np.where,np.digitized。其中一个应该适合您的需要。我正在研究它。然而,这个解决方案仍然有
for i..
循环。你认为这是不可避免的吗?谢谢,这正是我所需要的。计算时间减少了20倍,太棒了!不客气,我很高兴它有帮助。但是,我仍然对你计时结果的实际数字感兴趣,因为我测量了一个事实r 200.对于10000x20x20数据数组,您的代码需要大约450ms,上述解决方案需要大约2ms。有关结果,请参阅我的编辑。补充:如果您不使用
astype(int)
您甚至更快一点-这里不需要,显然转换是在动态总结时完成的。当然,这不是额外的因素,而是大约25%…请参阅我的编辑;计时很快就会到来。使用您使用的代码,我得到类似的结果:对于循环,每个循环297 ms±6.72 ms(平均±标准偏差为7次运行,每个循环10次),每个循环的总和为1.68 ms±26.2µs(平均±标准偏差为7次运行,每个循环10次)。我之前可能误读了0。无论如何,再次感谢!
# <xarray.DataArray (lat: 5, lon: 5)>
# array([[1, 2, 1, 1, 2],
#        [2, 2, 0, 2, 0],
#        [2, 2, 2, 0, 2],
#        [0, 2, 2, 0, 1],
#        [0, 1, 1, 0, 2]])
# Coordinates:
#   * lat      (lat) float64 -5.0 -2.5 0.0 2.5 5.0
#   * lon      (lon) int32 33 35 37 39 41
import xarray as xr
import numpy as np

da_big = xr.DataArray(np.random.randint(290, 305, (10000, 5, 5)),
              dims=['time', 'lat', 'lon'],
              coords={'lat': [-5, -2.5, 0, 2.5, 5], 'lon': [33, 35, 37, 39, 41]})

def OP(darr, trange = (293,303)):
    zeros = darr[0]
    zeros.values = np.zeros((darr.sizes['lat'], darr.sizes['lon']))

    for i in range(0, (len(darr.time))):
        int_array = 1*(darr.values[i] >= trange[0]) * (darr.values[i] <= trange[1])
        zeros = zeros + int_array

    return zeros.values
def SumAxis(darr, trange = (293,303)):
    return ((darr >= trange[0]) & (darr <= trange[1])).sum(axis=0)

%timeit -n10 OP(da_big)
%timeit -n10 SumAxis(da_big)

# 466 ms ± 13.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 1.89 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)