2

低,我在升级到 1.5.1 后遇到了 numpy.choose 的回归。据我所知,过去的版本(和数字)支持无限数量的潜在选择。“新”选择限制为 32。 这是另一位用户感叹回归的帖子。

我有一个包含 100 个选项 (0-99) 的列表,用于修改数组。作为一种解决方法,我正在使用以下代码。可以理解,它比使用选择慢 7 倍。我不是 C 程序员,虽然我想解决 numpy 问题,但我想知道还有哪些其他可能更快的解决方法。想法?

d={...} #A dictionary with my keys and their new mappings
for key, value in d.iteritems():
    array[array==key]=value 
4

4 回答 4

2

我收集到有d钥匙。在这种情况下,解决方案非常简单。首先,将 的值写入NumPy 数组,以某种方式——这似乎是这些值的自然数据结构。然后您可以使用替换的值访问新数组099dvaluesd[i] == values[i]

values[array]

如果您想array就地修改,只需执行

array[:] = values[array]
于 2012-07-19T22:28:07.610 回答
2

在 Numpy 文档中,有一个示例说明了选择函数的简化版本的外观。

[...] 这个函数不像从下面的代码描述中看起来那么简单(在 ndi = numpy.lib.index_tricks 下面):

np.choose(a,c) == np.array([c[a[I]][I] for I in ndi.ndindex(a.shape)]).

请参阅https://docs.scipy.org/doc/numpy/reference/generated/numpy.choose.html

将其放入函数中可能如下所示:

import numpy

def choose(selector, choices):
    """
    A simplified version of the numpy choose function to workaround the 32
    choices limit.
    """
    return numpy.array([choices[selector[idx]][idx] for idx in numpy.lib.index_tricks.ndindex(selector.shape)]).reshape(selector.shape)

我不确定这在效率方面是如何转化的,以及与功能相比何时会发生故障numpy.choose。但这对我来说效果很好。请注意,patched 函数假定选项中的条目是可下标的。

于 2019-06-18T09:57:23.350 回答
0

我不确定效率并且它不是到位的(注意:我不经常使用 numpy - 所以有点生疏):

import numpy as np

d = {0: 5, 1: 3, 2: 20}
data = np.array([[1, 0, 2], [2, 1, 1], [1, 0, 1]])
new_data = np.array([d.get(i, i) for i in data.flat]).reshape(data.shape) # adapt for list/other
于 2012-07-19T22:47:02.410 回答
0

在对小鼠胚胎的显微图像进行着色时,我遇到了一种choose实现需求,其中选择的数量为数百(数百个小鼠胚胎细胞)。

https://github.com/flatironinstitute/mouse_embryo_labeller

由于我不确定上述建议是通用的还是快速的,所以我写了这个替代方案:

import numpy as np

def big_choose(indices, choices):
    "Alternate to np.choose that supports more than 30 choices."
    indices = np.array(indices)
    if (indices.max() <= 30) or (len(choices) <= 31):
        # optimized fallback
        choices = choices[:31]
        return np.choose(indices, choices)
    result = 0
    while (len(choices) > 0) and not np.all(indices == -1):
        these_choices = choices[:30]
        remaining_choices = choices[30:]
        shifted_indices = indices + 1
        too_large_indices = (shifted_indices > 30).astype(np.int)
        clamped_indices = np.choose(too_large_indices, [shifted_indices, 0])
        choices_with_default = [result] + list(these_choices)
        result = np.choose(clamped_indices, choices_with_default)
        choices = remaining_choices
        if len(choices) > 0:
            indices = indices - 30
            too_small = (indices < -1).astype(np.int)
            indices = np.choose(too_small, [indices, -1])
    return result

请注意,通用函数尽可能使用底层实现。

于 2021-09-28T13:26:45.930 回答