[英]How to vectorize a function having ndarray of different shape as an argument?
我有以下功能:
def reshape_to_array(in_dict, pattern):
vec_func = np.frompyfunc(in_dict.get, 1, 1)
return vec_func(pattern)
func = np.frompyfunc(reshape_to_array,2,1)
輸入:
dump = np.array([[{'HH': 'a00', 'HV': 'b00', 'VH': 'c00', 'VV': 'd00'},
{'HH': 'a01', 'HV': 'b01', 'VH': 'c01', 'VV': 'd01'},
{'HH': 'a02', 'HV': 'b02', 'VH': 'c02', 'VV': 'd02'},
{'HH': 'a03', 'HV': 'b03', 'VH': 'c03', 'VV': 'd03'}],
[{'HH': 'a10', 'HV': 'b10', 'VH': 'c10', 'VV': 'd10'},
{'HH': 'a11', 'HV': 'b11', 'VH': 'c11', 'VV': 'd11'},
{'HH': 'a02', 'HV': 'b02', 'VH': 'c02', 'VV': 'd02'},
{'HH': 'a13', 'HV': 'b13', 'VH': 'c13', 'VV': 'd13'}],
[{'HH': 'a20', 'HV': 'b20', 'VH': 'c20', 'VV': 'd20'},
{'HH': 'a21', 'HV': 'b21', 'VH': 'c21', 'VV': 'd21'},
{'HH': 'a22', 'HV': 'b22', 'VH': 'c22', 'VV': 'd22'},
{'HH': 'a23', 'HV': 'b23', 'VH': 'c23', 'VV': 'd23'}],
[{'HH': 'a30', 'HV': 'b30', 'VH': 'c30', 'VV': 'd30'},
{'HH': 'a31', 'HV': 'b31', 'VH': 'c31', 'VV': 'd31'},
{'HH': 'a32', 'HV': 'b32', 'VH': 'c32', 'VV': 'd32'},
{'HH': 'a33', 'HV': 'b33', 'VH': 'c33', 'VV': 'd33'}]])
pattern = np.array([['HH', 'HV'], ['VH', 'VV']])
當我執行:
x = func(dump, pattern)
它拋出 ryuntime 錯誤:
ValueError: operands could not be broadcast together with shapes (4,4) (2,2)
但是,如果我按以下方式修改reshape_to_array
函數:
# pattern is global
pattern = np.array([['HH', 'HV'], ['VH', 'VV']])
def reshape_to_array(in_dict):
vec_func = np.frompyfunc(in_dict.get, 1, 1)
return vec_func(pattern)
func = np.frompyfunc(reshape_to_array,1,1)
並執行func(dump)
它成功執行並返回預期的(正確的)輸出。 這是:
x = np.array([[array([['a00', 'b00'],
['c00', 'd00']]),
array([['a01', 'b01'],
['c01', 'd01']]),
array([['a02', 'b02'],
['c02', 'd02']]),
array([['a03', 'b03'],
['c03', 'd03']])],
[array([['a10', 'b10'],
['c10', 'd10']]),
array([['a11', 'b11'],
['c11', 'd11']]),
array([['a02', 'b02'],
['c02', 'd02']]),
array([['a13', 'b13'],
['c13', 'd13']])],
[array([['a20', 'b20'],
['c20', 'd20']]),
array([['a21', 'b21'],
['c21', 'd21']]),
array([['a22', 'b22'],
['c22', 'd22']]),
array([['a23', 'b23'],
['c23', 'd23']])],
[array([['a30', 'b30'],
['c30', 'd30']]),
array([['a31', 'b31'],
['c31', 'd31']]),
array([['a32', 'b32'],
['c32', 'd32']]),
array([['a33', 'b33'],
['c33', 'd33']])]])
我的問題是:
您的第一個func
接受 2 個輸入,它們相互廣播,並且元素元組被傳遞給reshape_to_array
dump
是 (4,4), pattern
是 (2,2)。 錯誤說它可以配對 2 - 如果您了解廣播,這應該很明顯。
如果您將dump
減少到 (2,2) (或 (2,1) 或 (1,2)) 它應該可以工作。 (1,4) 或 (4,1) 的pattern
也是如此。
在frompyfunc
情況下,外部frompyfunc
將每個 (4,4) dump
元素傳遞給reshape_to_array
。 和(4,4)
模式被評估。
我懷疑x = func(dump[:,:,np.newaxis, np.newaxis], pattern)
會起作用,生成相同的值,但在 (4,4,2,2) 數組中。 使用不同的np.newaxis
我們可以產生 (4,2,4,2) 等。
In [291]: fn = lambda in_dict, pattern: in_dict.get(pattern)
In [299]: fn1 = np.frompyfunc(fn,2,1)
使用 (4,4) dump
,我可以使用 (1,4) pattern
(或 (4,1)):
In [300]: fn1(dump, pattern.reshape(1,4))
Out[300]:
array([['a00', 'b01', 'c02', 'd03'],
['a10', 'b11', 'c02', 'd13'],
['a20', 'b21', 'c22', 'd23'],
['a30', 'b31', 'c32', 'd33']], dtype=object)
如果我將newaxis
添加到dump
我可以獲得一個 (4,4,2,2) 數組:
In [302]: fn1(dump[:,:,None,None], pattern)
Out[302]:
array([[[['a00', 'b00'],
['c00', 'd00']],
[['a01', 'b01'],
['c01', 'd01']],
[['a02', 'b02'],
['c02', 'd02']],
....
[['a32', 'b32'],
['c32', 'd32']],
[['a33', 'b33'],
['c33', 'd33']]]], dtype=object)
In [303]: _.shape
Out[303]: (4, 4, 2, 2)
這些與您的x
相同,除了沒有 (4,4) (2,2) 嵌套。
如果我復制粘貼你的x
,它會產生一個 (4,4,2,2) 'U3' 數組(它不保留嵌套),然后比較:
In [309]: np.all(xx == Out[302].astype('U3'))
Out[309]: True
您可以將上一個版本包裝在函數定義中:
def foo(pattern):
def reshape_to_array(in_dict):
vec_func = np.frompyfunc(in_dict.get, 1, 1)
return vec_func(pattern)
func = np.frompyfunc(reshape_to_array,1,1)
return func
將用作:
In [313]: foo(pattern)
Out[313]: <ufunc '? (vectorized)'>
In [314]: foo(pattern)(dump)
# your x
In [334]: def reshape_to_array(in_dict, pattern=None):
...: vec_func = np.frompyfunc(in_dict.get, 1, 1)
...: return vec_func(pattern)
In [335]: f = np.vectorize(reshape_to_array, excluded=['pattern'], otypes=['O'])
In [336]: f(dump, pattern=pattern)
In [380]: def reshape_to_array1(in_dict, pattern=None):
...: vec_func = np.vectorize(in_dict.get, otypes=[complex])
...: return vec_func(pattern)
...:
...:
In [381]: f = np.vectorize(reshape_to_array1, excluded=['pattern'], otypes=['O
...: '])
In [382]: dd = np.array([{'HH': 1+j, 'HV': 1j, 'VH':2j, 'VV': 1+2j}])
In [383]: f(dd, pattern=pattern)
Out[383]:
array([array([[3.+0.j, 0.+1.j],
[0.+2.j, 1.+2.j]])], dtype=object)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.