numpy 运行包含map_blocks和reduce的计算时发生TypeError

hc2pp10m  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(67)

我很难诊断错误的原因。我的代码涉及对一些数组运行卷积(使用map_blocks),如果它们属于同一组变量,否则只记录2维数组。然后我执行argmax操作,并将结果添加到列表中,然后我们将其连接起来。
我试着用scheduler='single-threaded'参数运行compute,以帮助调试,但我仍然无法看到错误的原因。

import dask.array as da
from functools import reduce
import numpy as np

size = 100000
vals = da.linspace(0, 1, size)
nvars = 12
test = da.random.uniform(low=0, high=1, size=(100000, nvars, size), chunks=(100, nvars, size))

# number of total unique items corresponds to nvars
var_lookup = {
        'a': [0, 1],
        'b':
        [0, 1],
        'c': [0],
        'd': [0, 1],
        'e': [0],
        'f': [0, 1, 2],
        'g': [0],
    }

# Iterates over all 0 dimension coordinates
# and convolves relevant values from x and y
def custom_convolve(x,y):
    temp_lst = []
    for i in range(x.shape[0]):
        a = da.fft.rfft(x[i])
        b = da.fft.rfft(y[i])
        conv_res = da.fft.irfft(a * b, n = size)
        temp_lst.append(conv_res)
    res = da.stack(temp_lst, axis=0)
    return res

n_groups = len(var_lookup.keys())

counter = 0
group_cols = []
for i in var_lookup.keys():
    grp = var_lookup[i]
    # if group consists of 1 value, then just record that 2-dim array
    if len(grp)==1:
        temp =  test[:,counter,:]
        counter += 1
    else:
        test_list = []
        for _ in var_lookup[i]:
            test_list.append(test[:, counter, :])
            counter += 1
        temp = reduce(lambda x, y: da.map_blocks(custom_convolve, x, y, dtype='float32'), test_list)

    res = vals[da.argmax(temp, axis=1)]

    group_cols.append(res)

loc = da.stack(group_cols, axis=1)

字符串
运行计算时出错:

res = loc.compute()


从最后一行开始的错误追溯很长,但结束在这里

File c:\Users\x\lib\site-packages\dask\array\slicing.py:990, in check_index(axis, ind, dimension)
    987 elif ind is None:
    988     return
--> 990 elif ind >= dimension or ind < -dimension:
    991     raise IndexError(
    992         f"Index {ind} is out of bounds for axis {axis} with size {dimension}"
    993     )

TypeError: '>=' not supported between instances of 'str' and 'int'


可能是reduce函数与map_blocks耦合导致了问题?

调试尝试更新1:

我使用pdb,将代码转换为.py文件,将计算参数更改为scheduler ='single-threaded'),在for i行之后添加set_trace并逐步执行。它只会在我进入计算步骤时出现相同的错误,所以没有帮助。

调试尝试更新2:

我已经确定了问题的确切路线。我稍微简化了代码,以确保它不是reduce函数,并消除了循环。

size = 10000
x_vals = da.linspace(0, 1, 1000)
test = da.random.uniform(low=0, high=1, size=(size,4,1000), chunks=(size / 10, 1, 1000))

def simple_convolve(x, y):
    temp_lst = []
    for i in range(x.shape[0]):
        a = da.fft.rfft(x[i])
        b = da.fft.rfft(y[i])
        conv_res = da.fft.irfft(a * b, n = size)
        temp_lst.append(conv_res)
    res = da.stack(temp_lst, axis=0)
    return res

res = da.map_blocks(simple_convolve, test[:,0], test[:,1], dtype='float32')

temp = x_vals[da.argmax(res, axis=1)]


我们在这里得到一个错误。如果我们钻取,那么错误实际上来自于运行这个

da.argmax(res, axis=1)


因为错误是说我正在比较一个字符串和一个整数,所以我检查了res没有null和无穷大值:

# btw don't understand why just 1 compute still returns a dask array
da.isnan(res).sum().compute().compute()
0

(~da.isfinite(res)).sum().compute().compute()
0

crcmnpdw

crcmnpdw1#

https://dask.discourse.group/t/typeerror-on-da-argmax-when-executing-compute/2053中回答:
您需要在simple_convolve中使用Numpy数组,因为此方法应用于Dask Array块,即Numpy数组。它至少应该返回一个Numpy数组。

相关问题