一种高效压缩numpy数组(Python)的方法

4
我正在寻找一种高效的方法来压缩numpy数组。 我有一个像这样的数组:dtype=[(name, (np.str_,8), (job, (np.str_,8), (income, np.uint32)](这是我的最爱示例)。
如果我做这样的事情:my_array.compress(my_array['income'] > 10000),我会得到一个新的数组,其中只有收入> 10000,并且速度相当快。
但是,如果我想在列表中过滤工作:它不起作用!
my__array.compress(m_y_array['job'] in ['this', 'that'])

错误:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

所以我需要做类似于这样的事情:

np.array([x for x in my_array if x['job'] in ['this', 'that'])

这既丑陋又低效!

您有什么想法可以提高它的效率吗?


据我所知,以下所有的解决方案都涉及到复制数组(用于掩码)。因此,在我看来,它们中没有一个真正高效。 - user67416
3个回答

1

这可能不如您所希望的那么好,但我认为您可以做到:

mask = my_array['job'] == 'this'
for condition in ['that', 'other']:
  mask = numpy.logical_or(mask,my_array['job'] == condition)
selected_array = my_array[mask]

1

压缩numpy数组的最佳方法是使用pytables。 在处理大量数值数据时,它是事实上的标准。

import tables as t
hdf5_file = t.openFile('outfile.hdf5')
hdf5_file.createArray ......
hdf5_file.close()

0

如果你正在寻找一个仅使用numpy的解决方案,我认为你不会得到它。尽管它在内部执行了大量工作,但请考虑tabular包是否能以更少的“丑陋”方式实现你想要的功能。我不确定你是否能在不自己编写C扩展的情况下获得更高的“效率”。

顺便说一句,我认为这对于任何真实情况来说都足够高效和漂亮。

my_array.compress([x in ['this', 'that'] for x in my_array['job']])

作为使这个过程更加简洁高效的额外步骤,你可能不会在中间使用硬编码列表,而是会使用集合,因为如果列表中有多个项目,使用集合进行搜索比使用列表要快得多:
job_set = set(['this', 'that'])
my_array.compress([x in job_set for x in my_array['job']])

如果您认为这还不够高效,我建议进行基准测试,这样您就可以有信心,在尝试使其更加高效时,您正在明智地利用时间。


谢谢!虽然不是纯numpy,但确实相当高效和漂亮;) 我将列表作为元组放置,这也很好(尚未进行基准测试...) - Louis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接