Estoy tratando de convertir una parte del código MATLAB, y esta es una línea con la que estoy luchando:

f = 0
wlab = reshape(bsxfun(@times,cat(3,1-f,f/2,f/2),lab),[],3)

Se me ocurrió

wlab = lab*(np.concatenate((3,1-f,f/2,f/2))) 

¿Cómo lo remodelo ahora?

1
user4414636 9 may. 2016 a las 12:12

4 respuestas

La mejor respuesta

MATLAB

 reshape(x,[],3)

Es el equivalente de numpy

 np.reshape(x,(-1,3))

[] y -1 son marcadores de posición para 'completar la forma correcta aquí'.

===============

Acabo de probar que la expresión de MATLAB es Octave, está en una máquina diferente, así que resumiré la acción.

Para lab=1:6 (6 elementos) el bsxfun produce una matriz (1,6,3); reshape lo convierte en (6,3), es decir, simplemente elimina la primera dimensión. El cat produce una matriz (1,1,3).

np.reshape(np.array([1-f,f/2,f/2])[None,None,:]*lab[None,:,None],(-1,3))

Para lab con forma (n, m), bsxfun produce una matriz (n, m, 3); la remodelación lo haría (n * m, 3)

Entonces, para un 2d lab, el numpy necesita ser

np.array([1-f,f/2,f/2])[None,None,:]*lab[:,:,None]

(En MATLAB, lab siempre será 2d (o mayor), por lo que este segundo caso está más cerca de su acción, incluso si n es 1).

=======================

np.array([1-f,f/2,f/2])*lab[...,None]

Manejaría cualquier forma lab

Si hago la octava lab (4,2,3), el `bsxfun también es (4,2,3)

La expresión numpy coincidente sería

In [94]: (np.array([1-f,f/2,f/2])*lab).shape
Out[94]: (4, 2, 3)

numpy agrega dimensiones al comienzo de la matriz (3,) para que coincida con las dimensiones de lab, efectivamente

(np.array([1-f,f/2,f/2])[None,None,:]*lab) # for 3d lab

Si f=0, entonces la matriz es [1,0,0], por lo que esto tiene el efecto de poner a cero los valores en la última dimensión de lab. En efecto, cambiando el 'color'.

2
hpaulj 9 may. 2016 a las 19:28

No lo haré por su código, sino más bien como conocimiento general:

bsxfun es una función que llena un vacío en MATLAB que Python no necesita llenar: difusión.

La radiodifusión es algo en lo que si una matriz que se multiplica / agrega / lo que sea similar no tiene el mismo tamaño que la otra que se usa, la matriz se repetirá.

Entonces, en Python, si tiene una matriz 3D A y desea multiplicar cada segmento 2D con una matriz B que es 2D, no necesita nada más, Python transmitirá {{X2} } para ti, repetirá la matriz una y otra vez. A*B será suficiente. Sin embargo, en MATLAB eso generará un error Matrix dimension mismatch. Para superar eso, usaría bsxfun como bsxfun(@times,A,B) y esto transmitirá (repetirá) B en la tercera dimensión de A.

Esto significa que convertir bsxfun a python generalmente no requiere nada.

5
Ander Biguri 9 may. 2016 a las 09:39

En Python, si usa numpy, no necesita hacer ninguna transmisión, ya que esto se hace automáticamente por usted.

Por ejemplo, mirar el siguiente código debería aclararlo:

>>> import numpy as np
>>> a = np.array([[1, 2, 3], [3, 4, 5], [6, 7, 8], [9, 10, 100]])
>>> b = np.array([1, 2, 3])
>>>
>>> a
    array([[  1,   2,   3],
           [  3,   4,   5],
           [  6,   7,   8],
           [  9,  10, 100]])
>>> b
array([1, 2, 3])
>>>
>>> a - b
    array([[ 0,  0,  0],
           [ 2,  2,  2],
           [ 5,  5,  5],
           [ 8,  8, 97]])
>>>
0
ncaralicea 4 jul. 2017 a las 18:30

Es equivalente a

import numpy as np
wlab = np.kron([1-f,f/2,f/2],lab.reshape(-1,1))
0
percusse 9 may. 2016 a las 12:54