将numpy数组转换为映射到行的值的dict

2024-09-30 10:40:32 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个2dnumpy数组,其中每一行表示一个唯一的项,而行中的每一列表示分配给该项的标签。例如,在这个实例中,一个10x25数组将表示10个项目,每个项目最多有25个标签。你知道吗

将其转换为dict(或者另一个适当的数据类型,如果可以按长度排序的话,还可以加分)的最有效方法是什么?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

Tags: 项目实例方法in列表排序is标签
3条回答

更新:添加按长度排序。你知道吗

我们可以使用高级索引来创建按项目和标签索引的网格。 然后我们可以在列上迭代并使用flatnonzero来获得项目id:

>>> 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中的一个保证特性。你知道吗

在使用OrderedDict按观察数排序之前,可以使用collections.defaultdict

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])])

您只需定义一个{}并遍历数组,边添加值,如下所示:

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(N2。这是因为set()是线性的,被称为N次。而且,集合成员是常数时间。你知道吗

相关问题 更多 >

    热门问题