2009-12-21 25 views

Trả lời

17

Nếu bạn muốn tập hợp các phần tử, đây là một tập hợp khác, có thể nhanh hơn ay:

y = set(x.flatten()) 

PS: sau khi thực hiện so sánh giữa x.flat, x.flatten(), và x.ravel() trên một mảng 10x100, tôi phát hiện ra rằng tất cả họ đều thực hiện vào khoảng cùng tốc độ. Đối với một mảng 3x3, phiên bản nhanh nhất là phiên bản iterator:

y = set(x.flat) 

mà tôi muốn giới thiệu vì nó là phiên bản bộ nhớ ít tốn kém (nó quy mô lên tốt với kích thước của mảng).

PS: Ngoài ra còn có một chức năng NumPy rằng làm điều gì đó tương tự:

y = numpy.unique(x) 

này không tạo ra một mảng với các yếu tố tương tự như set(x.flat) NumPy, nhưng như là một mảng NumPy. Điều này là rất nhanh (gần 10 lần nhanh hơn), nhưng nếu bạn cần một set, sau đó làm set(numpy.unique(x)) là một chút chậm hơn so với các thủ tục khác (xây dựng một bộ đi kèm với một chi phí lớn).

+2

Đề xuất tốt! Bạn cũng có thể sử dụng set (x.ravel()), thực hiện điều tương tự nhưng chỉ tạo một bản sao nếu cần. Hoặc, tốt hơn, sử dụng set (x.flat). x.flat là một iterator trên các phần tử của mảng phẳng, nhưng không lãng phí thời gian thực sự làm phẳng mảng – musicinmybrain

+0

@musicinmybrain: các điểm rất tốt! Cảm ơn bạn! – EOL

+2

CẢNH BÁO: câu trả lời này * sẽ không * cung cấp cho bạn một tập hợp các vectơ, mà là tập hợp các số. Nếu bạn muốn một tập hợp các vectơ thì hãy xem câu trả lời của miku bên dưới để chuyển đổi các vectơ thành bộ dữ liệu – conradlee

9

Các đối tác không thay đổi cho một mảng là các tuple, do đó, hãy thử chuyển đổi các mảng của mảng thành một mảng của các bộ:

>> from numpy import * 
>> x = array([[3,2,3],[4,4,4]]) 

>> x_hashable = map(tuple, x) 

>> y = set(x_hashable) 
set([(3, 2, 3), (4, 4, 4)]) 
+0

và làm thế nào để tôi dễ dàng/chuyển đổi có hiệu quả trở lại vào một danh sách? – user989762

+0

'bản đồ (mảng, y)' – Manuel

3

Nếu bạn muốn có một bộ các yếu tố:

>> y = set(e for r in x 
      for e in r) 
set([2, 3, 4]) 

Đối với một tập hợp các hàng:

>> y = set(tuple(r) for r in x) 
set([(3, 2, 3), (4, 4, 4)]) 
6

Những câu trả lời ở trên có tác dụng nếu bạn muốn tạo một bộ ra khỏi yếu tố chứa trong một ndarray, nhưng nếu bạn muốn tạo ra một tập hợp các ndarray đối tượng - hoặc sử dụng ndarray đối tượng như phím trong một cuốn từ điển - sau đó bạn sẽ phải cung cấp một wrapper hashable cho chúng. Xem mã dưới đây cho một ví dụ đơn giản:

from hashlib import sha1 

from numpy import all, array, uint8 


class hashable(object): 
    r'''Hashable wrapper for ndarray objects. 

     Instances of ndarray are not hashable, meaning they cannot be added to 
     sets, nor used as keys in dictionaries. This is by design - ndarray 
     objects are mutable, and therefore cannot reliably implement the 
     __hash__() method. 

     The hashable class allows a way around this limitation. It implements 
     the required methods for hashable objects in terms of an encapsulated 
     ndarray object. This can be either a copied instance (which is safer) 
     or the original object (which requires the user to be careful enough 
     not to modify it). 
    ''' 
    def __init__(self, wrapped, tight=False): 
     r'''Creates a new hashable object encapsulating an ndarray. 

      wrapped 
       The wrapped ndarray. 

      tight 
       Optional. If True, a copy of the input ndaray is created. 
       Defaults to False. 
     ''' 
     self.__tight = tight 
     self.__wrapped = array(wrapped) if tight else wrapped 
     self.__hash = int(sha1(wrapped.view(uint8)).hexdigest(), 16) 

    def __eq__(self, other): 
     return all(self.__wrapped == other.__wrapped) 

    def __hash__(self): 
     return self.__hash 

    def unwrap(self): 
     r'''Returns the encapsulated ndarray. 

      If the wrapper is "tight", a copy of the encapsulated ndarray is 
      returned. Otherwise, the encapsulated ndarray itself is returned. 
     ''' 
     if self.__tight: 
      return array(self.__wrapped) 

     return self.__wrapped 

Sử dụng lớp wrapper là đơn giản đủ:

>>> from numpy import arange 

>>> a = arange(0, 1024) 
>>> d = {} 
>>> d[a] = 'foo' 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
TypeError: unhashable type: 'numpy.ndarray' 
>>> b = hashable(a) 
>>> d[b] = 'bar' 
>>> d[b] 
'bar' 
Các vấn đề liên quan