Jika Anda ingin menghindari biaya memori dari konversi ke serangkaian tupel atau struktur data serupa lainnya, Anda dapat mengeksploitasi susunan terstruktur numpy.
Caranya adalah dengan melihat array asli Anda sebagai array terstruktur di mana setiap item sesuai dengan deretan array asli. Ini tidak membuat salinan, dan cukup efisien.
Sebagai contoh cepat:
import numpy as np
data = np.array([[1, 1, 1, 0, 0, 0],
[0, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 0, 0],
[1, 1, 1, 0, 0, 0],
[1, 1, 1, 1, 1, 0]])
ncols = data.shape[1]
dtype = data.dtype.descr * ncols
struct = data.view(dtype)
uniq = np.unique(struct)
uniq = uniq.view(data.dtype).reshape(-1, ncols)
print uniq
Untuk memahami apa yang terjadi, lihat hasil perantara.
Setelah kami melihat sesuatu sebagai array terstruktur, setiap elemen dalam array adalah baris di array asli Anda. (Pada dasarnya, ini adalah struktur data yang mirip dengan daftar tupel.)
In [71]: struct
Out[71]:
array([[(1, 1, 1, 0, 0, 0)],
[(0, 1, 1, 1, 0, 0)],
[(0, 1, 1, 1, 0, 0)],
[(1, 1, 1, 0, 0, 0)],
[(1, 1, 1, 1, 1, 0)]],
dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8'), ('f4', '<i8'), ('f5', '<i8')])
In [72]: struct[0]
Out[72]:
array([(1, 1, 1, 0, 0, 0)],
dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8'), ('f4', '<i8'), ('f5', '<i8')])
Setelah kami jalankan numpy.unique
, kami akan mendapatkan array terstruktur kembali:
In [73]: np.unique(struct)
Out[73]:
array([(0, 1, 1, 1, 0, 0), (1, 1, 1, 0, 0, 0), (1, 1, 1, 1, 1, 0)],
dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8'), ('f4', '<i8'), ('f5', '<i8')])
Yang kemudian perlu kita lihat sebagai array "normal" ( _
menyimpan hasil perhitungan terakhir ipython
, itulah mengapa Anda melihatnya _.view...
):
In [74]: _.view(data.dtype)
Out[74]: array([0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0])
Dan kemudian membentuk kembali menjadi array 2D ( -1
adalah placeholder yang memberitahu numpy untuk menghitung jumlah baris yang benar, berikan jumlah kolom):
In [75]: _.reshape(-1, ncols)
Out[75]:
array([[0, 1, 1, 1, 0, 0],
[1, 1, 1, 0, 0, 0],
[1, 1, 1, 1, 1, 0]])
Jelas, jika Anda ingin lebih ringkas, Anda bisa menuliskannya sebagai:
import numpy as np
def unique_rows(data):
uniq = np.unique(data.view(data.dtype.descr * data.shape[1]))
return uniq.view(data.dtype).reshape(-1, data.shape[1])
data = np.array([[1, 1, 1, 0, 0, 0],
[0, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 0, 0],
[1, 1, 1, 0, 0, 0],
[1, 1, 1, 1, 1, 0]])
print unique_rows(data)
Yang mengakibatkan:
[[0 1 1 1 0 0]
[1 1 1 0 0 0]
[1 1 1 1 1 0]]