Mam dużą tablicę (arr) kształtu (62000000, 2), w której każdy wiersz reprezentuje dwa indeksy całkowite, które chcę przekazać do innej funkcji. Struktura wygląda mniej więcej tak:

def myfunc(a, b):
    return a + b
def pair_func(two_elem_arr):  # takes a 2-element vector/array
    return myfunc(*two_elem_arr)

Próbowałem użyć dask do zrównoleglenia całego procesu, ale mam następujący problem.

Kiedy używasz apply_along_axis do drukowania, pierwszym elementem wynikowej pętli tła jest tajemniczy [1]. Dokładnie ta sama procedura działa doskonale, gdy używasz zwykłego numpy:

import numpy as np
import dask.array as da

arr = np.repeat(np.arange(10), 2).reshape((10, 2))
darr = da.from_array(arr)

print('numpy version:')
np.apply_along_axis(arr=arr, axis=1, func1d=print)
print('\ndask version:')
da.apply_along_axis(arr=darr, axis=1, func1d=print).compute()

Wynik:

numpy version:
[0 0]
[1 1]
[2 2]
[3 3]
[4 4]
[5 5]
[6 6]
[7 7]
[8 8]
[9 9]

dask version:
[1]   <------------- ?
[0 0]
[1 1]
[2 2]
[3 3]
[4 4]
[5 5]
[6 6]
[7 7]
[8 8]
[9 9]

Skąd się bierze to [1]?

Wydaje się, że jest to przyczyną niepowodzenia w zastosowaniu pożądanej funkcji:

np.apply_along_axis(arr=arr, axis=1, func1d=pair_func)
da.apply_along_axis(arr=darr, axis=1, func1d=pair_func)

Wywołanie da.apply_along_axis powoduje następujący wyjątek:

TypeError: myfunc() missing 1 required positional argument: 'b'

Jeszcze bardziej zagmatwane jest to, że cały proces działa z dobrymi innymi funkcjami, takimi jak da.sum (a także np.sum w tym samym miejscu):

da.apply_along_axis(arr=darr, axis=1, func1d=da.sum).compute()

A więc właściwie dwa pytania,

  • dlaczego w danych wyjściowych funkcji da.apply_along_axis(...) znajduje się [1] i jak można to usunąć,
  • a jeśli nie, czy istnieją alternatywy umożliwiające osiągnięcie pożądanego rezultatu?

Z góry dziękuję

0
AdagioMolto 20 listopad 2019, 18:45

1 odpowiedź

Rozwiązanie jest ukryte w dokumentacji.

[…]

Uwagi

Jeśli nie podano żadnego z dtype lub shape, Dask próbuje je określić, wywołując func1d na tablicy fikcyjnej. Może to spowodować nieprawidłowe wartości dtype lub shape, dlatego zalecamy ich podanie. [...]

Kiedy podam shape=(1,) i dtype='int', wszystko działa dobrze. Wydaje mi się, że dodatkowe [1] jest wynikiem ustalenia dtype i shape przy użyciu fikcyjnej tablicy. Nadal nie sądzę, że powinno tak być.

da.apply_along_axis(arr=darr, axis=1, func1d=pair_func, shape=(1,), dtype='int')
0
Community 20 czerwiec 2020, 12:12