Concatenando dos matrices NumPy unidimensionales


266

Tengo dos matrices unidimensionales simples en NumPy . Debería poder concatenarlos usando numpy.concatenate . Pero recibo este error para el siguiente código:

TypeError: solo las matrices de longitud 1 se pueden convertir a escalares de Python

Código

import numpy
a = numpy.array([1, 2, 3])
b = numpy.array([5, 6])
numpy.concatenate(a, b)

¿Por qué?


Si desea concatenarlos (en una sola matriz) a lo largo de un eje, use np.concatenat(..., axis). Si quieres apilarlos verticalmente, úsalos np.vstack. Si desea apilarlos (en múltiples matrices) horizontalmente, use np.hstack. (Si desea apilarlos en profundidad, es decir, la tercera dimensión, use np.dstack). Tenga en cuenta que estos últimos son similares a los pandaspd.concat
smci

Respuestas:


372

La línea debe ser:

numpy.concatenate([a,b])

Las matrices que desea concatenar deben pasarse como una secuencia, no como argumentos separados.

De la documentación de NumPy :

numpy.concatenate((a1, a2, ...), axis=0)

Unir una secuencia de matrices juntas.

Intentaba interpretar su bcomo el parámetro del eje, por lo que se quejó de que no podía convertirlo en un escalar.


1
¡Gracias! solo curioso: ¿cuál es la lógica detrás de esto?
user391339

8
@ user391339, ¿y si quisieras concatenar tres matrices? La función es más útil para tomar una secuencia que si solo tomara dos matrices.
Winston Ewert

@WinstonEwert Suponiendo que el problema no sea que esté codificado con dos argumentos, puede usarlo como numpy.concatenate(a1, a2, a3)o numpy.concatenate(*[a1, a2, a3])si lo prefiere. Python es lo suficientemente fluido como para que la diferencia termine sintiéndose más cosmética que sustancial, pero es bueno cuando la API es consistente (por ejemplo, si todas las funciones numpy que toman listas de argumentos de longitud variable requieren secuencias explícitas).
Jim K.

@JimK. ¿Qué pasaría con el parámetro del eje?
Winston Ewert

1
Suponiendo que las cosas para concatenar son todos parámetros posicionales, podría mantener el eje como argumento de palabra clave, por ejemplo def concatx(*sequences, **kwargs)). No es ideal, ya que parece que no puede nombrar los argumentos de palabras clave explícitamente en la firma de esta manera, pero hay soluciones alternativas.
Jim K.

37

Hay varias posibilidades para concatenar matrices 1D, por ejemplo,

numpy.r_[a, a],
numpy.stack([a, a]).reshape(-1),
numpy.hstack([a, a]),
numpy.concatenate([a, a])

Todas esas opciones son igualmente rápidas para matrices grandes; para los pequeños, concatenatetiene una ligera ventaja:

ingrese la descripción de la imagen aquí

La trama se creó con perfplot :

import numpy
import perfplot

perfplot.show(
    setup=lambda n: numpy.random.rand(n),
    kernels=[
        lambda a: numpy.r_[a, a],
        lambda a: numpy.stack([a, a]).reshape(-1),
        lambda a: numpy.hstack([a, a]),
        lambda a: numpy.concatenate([a, a]),
    ],
    labels=["r_", "stack+reshape", "hstack", "concatenate"],
    n_range=[2 ** k for k in range(19)],
    xlabel="len(a)",
)

9
Las alternativas que todos usan np.concatenate. Simplemente dan masajes a la lista de entrada de varias maneras antes de la mano. np.stackpor ejemplo, agrega una dimensión adicional a todas las matrices de entrada. Mira su código fuente. Solo concatenatese compila.
hpaulj

1
Solo para agregar al comentario de @hpaulj: todas las veces convergen a medida que aumenta el tamaño de las matrices porque np.concatenatehace copias de las entradas. Este costo de memoria y tiempo supera el tiempo dedicado a "masajear" la entrada.
n1k31t4

31

El primer parámetro concatenatedebería ser una secuencia de matrices para concatenar:

numpy.concatenate((a,b)) # Note the extra parentheses.

10

Una alternativa es usar la forma abreviada de "concatenar" que es "r _ [...]" o "c _ [...]" como se muestra en el código de ejemplo a continuación (ver http://wiki.scipy.org / NumPy_for_Matlab_Users para obtener información adicional):

%pylab
vector_a = r_[0.:10.] #short form of "arange"
vector_b = array([1,1,1,1])
vector_c = r_[vector_a,vector_b]
print vector_a
print vector_b
print vector_c, '\n\n'

a = ones((3,4))*4
print a, '\n'
c = array([1,1,1])
b = c_[a,c]
print b, '\n\n'

a = ones((4,3))*4
print a, '\n'
c = array([[1,1,1]])
b = r_[a,c]
print b

print type(vector_b)

Lo que resulta en:

[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]
[1 1 1 1]
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.  1.  1.  1.  1.] 


[[ 4.  4.  4.  4.]
 [ 4.  4.  4.  4.]
 [ 4.  4.  4.  4.]] 

[[ 4.  4.  4.  4.  1.]
 [ 4.  4.  4.  4.  1.]
 [ 4.  4.  4.  4.  1.]] 


[[ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]] 

[[ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 1.  1.  1.]]

2
vector_b = [1,1,1,1] #short form of "array", esto simplemente no es cierto. vector_b será un tipo de lista Python estándar. Sin embargo, Numpy es bastante bueno para aceptar secuencias en lugar de forzar que todas las entradas sean tipos numpy.array.
Hannes Ovrén

2
Tienes razón, me equivoqué. Corregí mi código fuente y el resultado.
Semjon Mössinger

0

Aquí hay más enfoques para hacer esto usando numpy.ravel(), numpy.array()utilizando el hecho de que las matrices 1D pueden descomprimirse en elementos simples:

# we'll utilize the concept of unpacking
In [15]: (*a, *b)
Out[15]: (1, 2, 3, 5, 6)

# using `numpy.ravel()`
In [14]: np.ravel((*a, *b))
Out[14]: array([1, 2, 3, 5, 6])

# wrap the unpacked elements in `numpy.array()`
In [16]: np.array((*a, *b))
Out[16]: array([1, 2, 3, 5, 6])

0

Algunos datos más de los documentos numpy :

Con sintaxis como numpy.concatenate((a1, a2, ...), axis=0, out=None)

axis = 0 para concatenación en fila axis = 1 para concatenación en columna

>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[5, 6]])

# Appending below last row
>>> np.concatenate((a, b), axis=0)
array([[1, 2],
       [3, 4],
       [5, 6]])

# Appending after last column
>>> np.concatenate((a, b.T), axis=1)    # Notice the transpose
array([[1, 2, 5],
       [3, 4, 6]])

# Flattening the final array
>>> np.concatenate((a, b), axis=None)
array([1, 2, 3, 4, 5, 6])

Espero que ayude !

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.