NumPy realidad tiene una función append, que parece que podría hacer lo que quiera, por ejemplo,
import numpy as NP
my_data = NP.random.random_integers(0, 9, 9).reshape(3, 3)
new_col = NP.array((5, 5, 5)).reshape(3, 1)
res = NP.append(my_data, new_col, axis=1)
su segundo fragmento (hstack) funcionará si se agrega otra línea, por ejemplo,
my_data = NP.random.random_integers(0, 9, 16).reshape(4, 4)
# the line to add--does not depend on array dimensions
new_col = NP.zeros_like(my_data[:,-1]).reshape(-1, 1)
res = NP.hstack((my_data, new_col))
hstack
g Tiene el mismo resultado que concatenate((my_data, new_col), axis=1)
, no estoy seguro de cómo se comparan en términos de rendimiento.
Si bien esa es la respuesta más directa a su pregunta, debo mencionar que bucle a través de una fuente de datos para poblar un objetivo a través de anexar , mientras que muy bien en pitón, no es idiomática NumPy. Aquí es por qué:
inicializar un array NumPy es relativamente caro, y con este patrón pitón convencional, de incurrir en que el costo, más o menos, en cada iteración de bucle (es decir, cada anexar a una matriz NumPy está más o menos como la inicialización una nueva matriz con un tamaño diferente).
Por esa razón, el patrón común en NumPy para la adición iterativa de columnas en una matriz 2D es inicializar una matriz de destino vacío una vez (o pre-asignar una única matriz 2D NumPy que tengan todas las columnas vacías) la pueblan sucesivamente esas columnas vacías mediante el establecimiento de la deseada por columnas offset (índice) - mucho más fácil mostrar que explicar:
>>> # initialize your skeleton array using 'empty' for lowest-memory footprint
>>> M = NP.empty(shape=(10, 5), dtype=float)
>>> # create a small function to mimic step-wise populating this empty 2D array:
>>> fnx = lambda v : NP.random.randint(0, 10, v)
pueblan gama NumPy como en el OP, excepto cada iteración simplemente re-establece los valores de M en desplazamientos sucesivos en columnas
>>> for index, itm in enumerate(range(5)):
M[:,index] = fnx(10)
>>> M
array([[ 1., 7., 0., 8., 7.],
[ 9., 0., 6., 9., 4.],
[ 2., 3., 6., 3., 4.],
[ 3., 4., 1., 0., 5.],
[ 2., 3., 5., 3., 0.],
[ 4., 6., 5., 6., 2.],
[ 0., 6., 1., 6., 8.],
[ 3., 8., 0., 8., 0.],
[ 5., 2., 5., 0., 1.],
[ 0., 6., 5., 9., 1.]])
, por supuesto, si usted no sabe de antemano lo que el tamaño de la matriz debe ser simplemente crear uno mucho más grande de lo que necesita y recortar las partes no utilizadas '' cuando termine de poblarlo
>>> M[:3,:3]
array([[ 9., 3., 1.],
[ 9., 6., 8.],
[ 9., 7., 5.]])
Publicación muy útil para un principiante numpy. Una pregunta rápida: ¿hay alguna razón por la cual se utiliza 'para el índice, ITM en enumerate (rango (5)):' en lugar de, por ejemplo, 'for x in range (5):' ya que el índice y el itm tienen el mismo valor y solo se usa uno. –
@ JohnBarça gracias por los comentarios. Es posible que tenga razón en que los detalles de mi fragmento de código deberían haberse elegido con más cuidado, es decir, en mi ejemplo, el valor de 'índice' en cada iteración es de hecho el mismo que el valor de la variable de ciclo. Sin embargo, eso es un artefacto: los valores de estas dos variables probablemente no sean iguales en la práctica (p. Ej., El iterable es una lista que contiene valores para pasar a una función que crea matrices 1D que luego se "insertan" en la matriz objetivo) – doug