将元组列表转换为数组,其中每个元组的第一个元素是数组索引?

时间:2019-03-15 20:04:03

标签: python arrays numpy

在Python中,如何将几个元组列表转换为数组,其中每个元组的第一个元素是数组索引?此外,并非每个列表的每个项目都有元组,我希望那些缺失的项目填充0。

所以我有

a = [(0, 2.45), (1, 3.25), (2, 5.34)]
b = [(0, 7.46), (1, 5.64), (3, 3.45)]
c = [(0, 9.65), (1, 7.22)]

我想要

somefun(a, b, c)
>>> array([(2.45, 3.25, 5.34, 0.  ), (7.46, 5.64, 0.  , 3.45), (9.65, 7.22, 0.  , 0.  ])

我现在有一个解决方案,可以遍历列表,创建具有指定列的结构化数组,然后使用numpy.lib.refunction.stack_array(),但是这种方法很慢:

from numpy.lib import refunctions as rfn

row_list = []
for row in [a, b]:
    index = [(str(i[0]), 'f4') for i in row]
    value = [tuple([i[1] for i in row])]
    row_list.append(np.array(value, dtype=index))

result = np.ma.filled(rfn.stack_arrays(row_list, usemask=True), fill_value = 0)

我有成千上万个这样的列表,我想组合成一个数组,所以我正在寻找更快的东西。也许还有一种我不知道的更合适的numpy方法。感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您可以使用以下功能:

from itertools import chain

a = [(0, 2.45), (1, 3.25), (2, 5.34)]
b = [(0, 7.46), (1, 5.64), (3, 3.45)]
c = [(0, 9.65), (1, 7.22)]

def func(*lists):
    max_ind = max(ind for ind, _ in chain.from_iterable(lists))
    result = []
    for l in lists:
        d = dict(l)
        t = tuple(d.get(ind, 0.) for ind in range(max_ind + 1))
        result.append(t)
    return result

print(func(a, b, c))
# [(2.45, 3.25, 5.34, 0.0), (7.46, 5.64, 0.0, 3.45), (9.65, 7.22, 0.0, 0.0)]

或者,您可以将itemgetter()defaultdict()一起使用:

from itertools import chain
from collections import defaultdict
from operator import itemgetter

def func(*lists):
    max_ind = max(ind for ind, _ in chain.from_iterable(lists))
    iget = itemgetter(*range(max_ind + 1))
    return [iget(defaultdict(float, l)) for l in lists]

print(func(a, b, c))
# [(2.45, 3.25, 5.34, 0.0), (7.46, 5.64, 0.0, 3.45), (9.65, 7.22, 0.0, 0.0)]