Estoy intentando escribir una función que asigne 2d-ndarray a 2d-ndarray. Las filas de la matriz de entrada se pueden procesar independientemente y habrá una correspondencia de 1 a 1 entre las filas de la entrada y las filas de la salida. Para cada fila de la entrada, se computará la expansión polinómica de un orden dado para la fila (ver docstring para un ejemplo). La implementación actual funciona; sin embargo, requiere un bucle explícito sobre las filas y la duplicación de filas en "powerMatrix"). ¿Es posible obtener el mismo resultado con una sola llamada a numpy.power? Por cierto: el orden de las entradas en las filas del resultado no me importa.2d numpy.power para la expansión polinómica
import numpy
def polynomialFeatures(x, order):
""" Generate polynomial features of given order for data x.
For each row of ndarray x, the polynomial expansions are computed, i.e
for row [x1, x2] and order 2, the following row of the result matrix is
computed: [1, x1, x1**2, x2, x1*x2, x1**2*x2, x2**2, x1*x2**2, x1**2*x2**2]
Parameters
----------
x : array-like
2-D array; for each of its rows, the polynomial features are created
order : int
The order of the polynomial features
Returns
-------
out : ndarray
2-D array of shape (x.shape[0], (order+1)**x.shape[1]) containing the
polynomial features computed for the rows of the array x
Examples
--------
>>> polynomialFeatures([[1, 2, 3], [-1, -2, -3]], 2)
array([[ 1 3 9 2 6 18 4 12 36 1 3 9 2 6 18 4 12
36 1 3 9 2 6 18 4 12 36]
[ 1 -3 9 -2 6 -18 4 -12 36 -1 3 -9 2 -6 18 -4 12
-36 1 -3 9 -2 6 -18 4 -12 36]])
"""
x = numpy.asarray(x)
# TODO: Avoid duplication of rows
powerMatrix = numpy.array([range(order+1)] * x.shape[1]).T
# TODO: Avoid explicit loop, and use numpy's broadcasting
F = []
for i in range(x.shape[0]):
X = numpy.power(x[i], powerMatrix).T
F.append(numpy.multiply.reduce(cartesian(X), axis=1))
return numpy.array(F)
print numpy.all(polynomialFeatures([[1, 2, 3], [-1, -2, -3]], 2) ==
numpy.array([[1, 3, 9, 2, 6, 18, 4, 12, 36, 1,
3, 9, 2, 6, 18, 4, 12, 36, 1, 3,
9, 2, 6, 18, 4, 12, 36],
[1, -3, 9, -2, 6, -18, 4, -12, 36, -1,
3, -9, 2, -6, 18, -4, 12, -36, 1, -3,
9, -2, 6, -18, 4, -12, 36]]))
Gracias, Ene
EDIT: La cartesiano función que falta se define aquí: Using numpy to build an array of all combinations of two arrays
+1. [Borré un comentario tonto mío - le había pasado '[1,2,3]' a su función en lugar de '[[1,2,3]]', lo que por supuesto dio resultados igualmente tontos.] – DSM
Gracias a mucho, eso hizo el trabajo :-) – frisbee
¡Esta es una solución realmente elegante! Me gustaría utilizarlo en un pequeño proyecto en el que estoy trabajando si no te importa: https://github.com/dreamwalkerrr/mledu. (¿Le atribuirá este algoritmo vincular a esta respuesta si está bien?). Además, ¿podría decirme cuál sería la mejor manera de excluir los términos elevados a la 0ª potencia? – dreamwalker