2015-12-12 2 views
5

Учитывая массив размером 2 x d, массив M, я хочу подсчитать количество вхождений каждого столбца M. То есть, я ищу общую версию bincount.Подсчет числа столбцов в массиве numpy

Что я пробовал до сих пор: (1) Конвертированные столбцы в кортежи (2) Хешированные кортежи (через hash) в натуральную величину (3) использовали numpy.bincount.

Это кажется довольно неуклюжим. Кто-нибудь знает более элегантный и эффективный способ?

+0

Интересный вопрос. С нетерпением ждем решения, потому что моя первая и единственная мысль была именно тем, что вы сделали. – Reti43

+0

Итак, вы ожидаете список уникальных столбцов и их количество? Нужно ли сохранять порядок столбцов? – imp9

+0

Просьба указать код ваших попыток. –

ответ

4

Вы можете использовать collections.Counter:

>>> import numpy as np 
>>> a = np.array([[ 0, 1, 2, 4, 5, 1, 2, 3], 
...    [ 4, 5, 6, 8, 9, 5, 6, 7], 
...    [ 8, 9, 10, 12, 13, 9, 10, 11]]) 
>>> from collections import Counter 
>>> Counter(map(tuple, a.T)) 
Counter({(2, 6, 10): 2, (1, 5, 9): 2, (4, 8, 12): 1, (5, 9, 13): 1, (3, 7, 11): 
1, (0, 4, 8): 1}) 
1

Дано:

a = np.array([[ 0, 1, 2, 4, 5, 1, 2, 3], 
       [ 4, 5, 6, 8, 9, 5, 6, 7], 
       [ 8, 9, 10, 12, 13, 9, 10, 11]]) 
b = np.transpose(a) 
  1. Более эффективное решение, чем хэширования (по-прежнему требует манипуляций):

    создать представление массива с гибким типом данных np.void (см here), такие что каждая строка становится единым элементом. Преобразование в эту форму позволит использовать np.unique.

    %%timeit  
    c = np.ascontiguousarray(b).view(np.dtype((np.void, b.dtype.itemsize*b.shape[1]))) 
    _, index, counts = np.unique(c, return_index = True, return_counts = True) 
    #counts are in the last column, remember original array is transposed 
    >>>np.concatenate((b[idx], cnt[:, None]), axis = 1) 
    array([[ 0, 4, 8, 1], 
         [ 1, 5, 9, 2], 
         [ 2, 6, 10, 2], 
         [ 3, 7, 11, 1], 
         [ 4, 8, 12, 1], 
         [ 5, 9, 13, 1]]) 
    10000 loops, best of 3: 65.4 µs per loop 
    

    Отсчетов прилагаемых к уникальному колонкам a.

  2. Ваше решение для хэширования.

    %%timeit 
    array_hash = [hash(tuple(row)) for row in b] 
    uniq, index, counts = np.unique(array_hash, return_index= True, return_counts = True) 
    np.concatenate((b[idx], cnt[:, None]), axis = 1) 
    10000 loops, best of 3: 89.5 µs per loop 
    

Update: Решение Эф является наиболее эффективным и элегантным.

%%timeit 
Counter(map(tuple, a.T)) 
10000 loops, best of 3: 38.3 µs per loop 
Смежные вопросы