2016-10-20 8 views
0

Следующая функция предназначена для поиска уникальных строк массива:Поиск повторяющихся строк в Numpy массиве

def unique_rows(a): 
    b = np.ascontiguousarray(a).view(np.dtype((np.void, a.dtype.itemsize * a.shape[1]))) 
    _, idx = np.unique(b, return_index=True) 
    unique_a = a[idx] 
    return unique_a 

Например,

test = np.array([[1,0,1],[1,1,1],[1,0,1]]) 
unique_rows(test) 
[[1,0,1],[1,1,1]] 

Я считаю, что эта функция должна работать все но не может быть водонепроницаемым. В моем коде я хотел бы рассчитать, сколько уникальных положений существует для набора частиц. Частицы хранятся в массиве 2d, каждая строка соответствует положению частицы. Позиции имеют тип np.float64. Я также определил следующую функцию

def pos_tag(pos): 
    x,y,z = pos[:,0],pos[:,1],pos[:,2] 
    return (2**x)*(3**y)*(5**z) 

В принципе эта функция должна производить уникальное значение для любого (х, у, г) положения.

Однако, когда я использую эти функции для вычисления количества уникальных позиций в моем наборе частиц, они дают разные ответы. Это связано с некоторым возможным логическим недостатком в первой функции или второй функцией, не создающей уникального значения для каждой данной позиции?

EDIT: Пример использования

У меня есть длинный код, который производит 2d массив postions частиц.

partpos.shape = (6039539,3) 

Я тогда вычислить число уникальных строк следующим образом

len(unqiue_rows(partpos)) 
6034411 

И

posids = pos_tag(partpos) 
len(np.unique(posids)) 
5328871 
+0

Ваши позиции парит? –

+0

Да, они являются поплавками – Jack

+0

'' 'pos [:, 0]' '' * идентифицирует * первый столбец, если вы хотите, чтобы первая строка была '' 'pos [0,:]' ''. – wwii

ответ

-1
a = [[1,0,1],[1,1,1],[1,0,1]] 

# Convert rows to tuples so they're hashable, creating a generator thereof 
b = (tuple(row) for row in a) 

# Convert back to list of lists, after coercing to a set to eliminate non-unique rows 
unique_rows = list(list(row) for row in set(b)) 

Edit: Ну, это неудобно. Я просто понял, что я действительно не задал вопрос. Это все еще может быть ответом, который ищет OP, поэтому я оставлю его, но это не совсем то, что было задано. Простите за это.

+0

Является ли этот метод поиска уникальных строк независимо от двух методов, описанных в вопросе? Если это так, это может быть полезно для тестирования. – Jack

+0

Да, это более прямой питонический способ совершить то же самое. Основная проблема заключается в том, что он не обеспечивает одинаковый порядок строк при каждом запуске. Вы можете принудительно выполнить заказ, отсортировав его позже, среди других методов. –

1

Я считаю, что это несоответствие возникает из-за ошибки точности. Использование кода

print len(unique_rows(partpos.astype(np.float32))) 
print len(np.unique(pos_tag(partpos))) 

6034411 
6034411 

Однако с

print len(unique_rows(partpos.astype(np.float32))) 
print len(np.unique(pos_tag(partpos.astype(np.float32)))) 

6034411 
5328871 
Смежные вопросы