Chuyển đổi mảng numpy thành bộ


108

Lưu ý: Đây là yêu cầu đảo ngược của chuyển đổi tuple-to-array thông thường.

Tôi phải truyền một đối số cho một hàm (bọc c ++) dưới dạng một bộ tuple lồng nhau. Ví dụ, các công trình sau

X = MyFunction( ((2,2),(2,-2)) )

trong khi những thứ sau thì không

X = MyFunction( numpy.array(((2,2),(2,-2))) )
X = MyFunction( [[2,2],[2,-2]] )

Thật không may, đối số mà tôi muốn sử dụng đến với tôi dưới dạng một mảng phức tạp. Mảng đó luôn có kích thước 2xN đối với một số N, có thể khá lớn.

Có cách nào dễ dàng để chuyển đổi nó thành một tuple không? Tôi biết rằng tôi có thể lặp lại, tạo một bộ tuple mới, nhưng sẽ thích hơn nếu có một số quyền truy cập tốt mà mảng numpy cung cấp.

Nếu không thể làm điều này một cách độc đáo như tôi hy vọng, thì cách tốt nhất để làm điều đó bằng cách lặp lại, hoặc bất cứ điều gì?

Câu trả lời:


157
>>> arr = numpy.array(((2,2),(2,-2)))
>>> tuple(map(tuple, arr))
((2, 2), (2, -2))

29
Vì vậy, đối với một 1-d mảng đơn giảntuple(arr)
FindOutIslamNow

26

Đây là một chức năng sẽ làm điều đó:

def totuple(a):
    try:
        return tuple(totuple(i) for i in a)
    except TypeError:
        return a

Và một ví dụ:

>>> array = numpy.array(((2,2),(2,-2)))
>>> totuple(array)
((2, 2), (2, -2))

1
Tổng quát tốt đẹp. Tuy nhiên, là một người mới chơi python, tôi tự hỏi liệu có được coi là phong cách tốt khi sử dụng ngoại lệ cho một điều kiện gần như phổ biến như trạng thái không đặc biệt hay không. Ít nhất trong c ++, kiểm soát luồng bằng các ngoại lệ thường không được chấp nhận. Nó sẽ tốt hơn để kiểm tra nếu type(a)==numpy.ndarray?
Mike

9
Điều này khá phổ biến trong python vì khái niệm "gõ vịt" và EAFT, thêm tại đây: docs.python.org/glossary.html#term-duck-typing . Ưu điểm của phương pháp này là nó sẽ chuyển đổi bất kỳ chuỗi lồng nhau nào thành các bộ giá trị lồng nhau, không chỉ là một mảng. Một điều tôi nên làm mà tôi đã sửa là chỉ định lỗi nào tôi muốn xử lý bằng khối ngoại trừ.
Bi Rico

3
Trong C ++, các ngoại lệ chậm so với các điều kiện vì nhiều lý do. Trong Python, chúng gần như giống nhau về hiệu suất - đây là một trong những nơi mà chúng ta phải kiểm tra trực giác C ++ của mình ngay từ đầu.
dbn

8

Tôi không hài lòng, vì vậy cuối cùng tôi đã sử dụng cái này:

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

>>> tuple(a.reshape(1, -1)[0])
(1, 2, 3, 4, 5, 6)

Tôi không biết nó có nhanh hơn không, nhưng nó có vẻ hiệu quả hơn;)


3
Đó không phải là hình dạng mà tôi muốn cho chiếc tuple.
Mike

5

Một lựa chọn khác

tuple([tuple(row) for row in myarray])

Nếu bạn đang chuyển mảng NumPy sang các hàm C ++, bạn cũng có thể muốn xem bằng cách sử dụng Cython hoặc SWIG.


Điều đó không chuyển đổi thành tuple. Chuyển đổi thành một danh sách?
Peter

Bạn đã thử à? Nó tạo ra một tuple khi tôi chạy vào. Lưu ý rằng hàm cuối cùng được gọi là tuple, hàm này trả về một tuple. Nếu bạn chỉ có phần [...] mà không có bộ giá trị bên ngoài, bạn sẽ nhận được danh sách các bộ giá trị.
Greg von Winckel

có phương pháp nào nhanh hơn không?
Vicrobot

1
Bạn có thể tránh tạo ra các trung gian listbằng cách bỏ qua các dấu ngoặc vuông, tức là sử dụngtuple(tuple(row) for row in myarray)
norok2

1

Nếu bạn thích cắt dài, đây là một cách khác tuple (tuple (a_m.tolist ()) cho a_m trong a)

from numpy import array
a = array([[1, 2],
           [3, 4]])
tuple(tuple(a_m.tolist()) for a_m in a )

Đầu ra là ((1, 2), (3, 4))

Lưu ý chỉ (tuple (a_m.tolist ()) cho a_m trong a) sẽ cung cấp một biểu thức trình tạo. Sắp xếp lấy cảm hứng từ nhận xét của @ norok2 cho câu trả lời của Greg von Winckel

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.