Преобразование массива numpy в набор значений, отображаемых в строки - PullRequest
0 голосов
/ 22 мая 2018

Учтите, что у меня есть двумерный массив, где каждая строка представляет уникальный элемент, а каждый столбец в строке представляет метку, назначенную этому элементу.Например, массив 10 x 25 в этом случае будет представлять 10 элементов, каждый из которых имеет до 25 меток каждая.

Какой самый эффективный способ преобразовать это в dict (или другой соответствующий тип данных,бонусные баллы, если они могут быть отсортированы по длине), которые отображают метки на индексы строк, в которых эта метка встречается?Например, dict[1] вернет список индексов строк, которые содержат 1 в качестве метки.

Например,

Given:
    [1, 2, 3]
    [1, 0, 0]
    [1, 3, 0]

Result:
    1: 0, 1, 2 # 1 occurs in rows 0, 1, 2
    3: 0, 2    # 3 occurs in rows 0, 2
    0: 1, 2    # 0 occurs in rows 1, 2 (0 is padding for lack of labels)
    2: 0       # 2 occurs in row 0 only

Ответы [ 3 ]

0 голосов
/ 22 мая 2018

ОБНОВЛЕНИЕ : добавлено упорядочение по длине.

Мы можем использовать расширенную индексацию для создания сетки, индексированной по элементам и меткам.Затем мы можем перебрать столбцы и использовать flatnonzero для получения идентификаторов элементов:

>>> ex = [[1, 2, 3],
...       [1, 0, 0],
...       [1, 3, 0]]
>>> 
>>> m = len(ex)
>>> n = np.max(ex) + 1
>>> grid = np.zeros((m, n), int) # could also use a smaller dtype here
>>> grid[np.arange(m)[:, None], ex] = 1
>>> grid
array([[0, 1, 1, 1],
       [1, 1, 0, 0],
       [1, 1, 0, 1]])
>>> idx = np.argsort(np.count_nonzero(grid, 0))[::-1]
>>> dict(zip(idx, map(np.flatnonzero, grid.T[idx])))
{1: array([0, 1, 2]), 3: array([0, 2]), 0: array([1, 2]), 2: array([0])}

Обратите внимание, что словари запоминают порядок вставки своих ключей.Это деталь реализации в 3.6, но гарантированная возможность в 3.7.

0 голосов
/ 22 мая 2018

Вы можете просто определить {} и выполнить итерацию по массиву, добавляя значения по ходу, например:

def f(array):
    table = {} # Initialize the dict
    for rownumber, row in enumerate(array): # Goes through all of the rows, with associated numbering
        for element in set(row): # Deduplicate to avoid duplicate row numbers
            if element not in table: table[element] = [] # Initialize empty row list if this element is new
            table[element].append(rownumber+1) # Add the current row number to the associated list of rows
    return d

print(f([[1, 2, 3], [1, 0, 0], [1, 3, 0]]))

Этот подход O (N 2 *)1007 *) .Это достигается, поскольку set () является линейным и вызывается N раз.Кроме того, установить членство является постоянным временем.

0 голосов
/ 22 мая 2018

Вы можете использовать collections.defaultdict, прежде чем использовать OrderedDict для сортировки по количеству наблюдений:

import numpy as np
from collections import defaultdict, OrderedDict

A = np.array([[1, 2, 3],
              [1, 0, 0],
              [1, 3, 0]])

d = defaultdict(list)

for idx, row in enumerate(A):
    for i in set(row):
        d[i].append(idx)

res = OrderedDict(sorted(d.items(), key=lambda x: len(x[1]), reverse=True))

print(res)

OrderedDict([(1, [0, 1, 2]),
             (3, [0, 2]),
             (0, [1, 2]),
             (2, [0])])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...