Nối hai mảng NumPy một chiều


266

Tôi có hai mảng một chiều đơn giản trong NumPy . Tôi có thể nối chúng bằng cách sử dụng numpy.concatenate . Nhưng tôi nhận được lỗi này cho mã dưới đây:

TypeError: chỉ các mảng có độ dài-1 có thể được chuyển đổi sang vô hướng Python

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

Tại sao?


Nếu bạn muốn nối chúng (thành một mảng) dọc theo một trục, hãy sử dụng np.concatenat(..., axis). Nếu bạn muốn xếp chúng theo chiều dọc, sử dụng np.vstack. Nếu bạn muốn xếp chúng (thành nhiều mảng) theo chiều ngang, hãy sử dụng np.hstack. (Nếu bạn muốn xếp chúng theo chiều sâu, tức là chiều thứ 3, hãy sử dụng np.dstack). Lưu ý rằng cái sau tương tự như gấu trúcpd.concat
smci

Câu trả lời:


372

Dòng nên là:

numpy.concatenate([a,b])

Các mảng bạn muốn nối cần phải truyền vào dưới dạng một chuỗi, không phải là các đối số riêng biệt.

Từ tài liệu NumPy :

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

Tham gia một chuỗi các mảng với nhau.

Nó đã cố gắng diễn giải bthông số trục của bạn , đó là lý do tại sao nó phàn nàn rằng nó không thể chuyển đổi nó thành vô hướng.


1
cảm ơn! chỉ tò mò - logic đằng sau này là gì?
dùng391339

8
@ user391339, nếu bạn muốn ghép ba mảng thì sao? Hàm này hữu ích hơn trong việc lấy một chuỗi sau đó nếu nó chỉ mất hai mảng.
Winston Ewert

@WinstonEwert Giả sử vấn đề không phải là nó được mã hóa thành hai đối số, bạn có thể sử dụng nó như thế numpy.concatenate(a1, a2, a3)hoặc numpy.concatenate(*[a1, a2, a3])nếu bạn thích. Python đủ để sự khác biệt cuối cùng cảm thấy mỹ phẩm hơn đáng kể, nhưng thật tốt khi API phù hợp (ví dụ: nếu tất cả các hàm numpy có danh sách đối số độ dài thay đổi yêu cầu trình tự rõ ràng).
Jim K.

@JimK. Điều gì sẽ xảy ra với tham số trục?
Winston Ewert

1
Giả sử những thứ cần nối là tất cả các tham số vị trí, bạn có thể giữ trục làm đối số từ khóa, vd def concatx(*sequences, **kwargs)). Điều này không lý tưởng vì bạn dường như không thể đặt tên cho từ khóa được lập luận rõ ràng trong chữ ký theo cách này, nhưng có cách giải quyết.
Jim K.

37

Có một số khả năng để ghép các mảng 1D, ví dụ:

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

Tất cả các tùy chọn đều nhanh như nhau cho các mảng lớn; Đối với những người nhỏ, concatenatecó một cạnh nhẹ:

nhập mô tả hình ảnh ở đây

Cốt truyện được tạo ra với 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
Các phương án đều sử dụng np.concatenate. Họ chỉ cần xoa bóp danh sách đầu vào theo nhiều cách khác nhau trước khi ra tay. np.stackví dụ: thêm một chiều bổ sung cho tất cả các mảng đầu vào. Nhìn vào mã nguồn của họ. Chỉ concatenateđược biên soạn.
hpaulj

1
Chỉ cần thêm vào nhận xét của @hpaulj - số lần tất cả hội tụ khi kích thước của các mảng tăng lên vì np.concatenatetạo ra các bản sao của đầu vào. Bộ nhớ và chi phí thời gian này sau đó vượt xa thời gian 'mát xa' đầu vào.
n1k31t4

31

Tham số đầu tiên concatenatephải là một chuỗi các mảng để nối:

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

10

Một ist khác để sử dụng dạng "concatenate" ngắn là "r _ [...]" hoặc "c _ [...]" như được hiển thị trong mã ví dụ bên dưới (xem http://wiki.scipy.org / NumPy_for_Matlab_Users để biết thêm thông tin):

%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)

Kết quả nào trong:

[ 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", Đơn giản là nó sai. vector_b sẽ là một loại danh sách Python tiêu chuẩn. Tuy nhiên, Numpy khá giỏi trong việc chấp nhận các chuỗi thay vì buộc tất cả các đầu vào là các loại numpy.array.
Hannes Ovrén 23/12/13

2
Bạn đúng - tôi đã sai. Tôi đã sửa mã nguồn của mình cũng như kết quả.
Semjon Mössinger

0

Dưới đây là phương pháp tiếp cận để thực hiện điều này bằng cách sử dụng numpy.ravel(), numpy.array(), sử dụng thực tế là mảng 1D có thể giải nén vào các yếu tố đơn giản:

# 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

Một số sự kiện khác từ các tài liệu numpy :

Với cú pháp như numpy.concatenate((a1, a2, ...), axis=0, out=None)

trục = 0 đối với trục nối theo hàng-khôn ngoan = 1 đối với ghép nối theo cột

>>> 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])

Tôi hy vọng nó sẽ giúp!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.