从for循环到矩阵计算

2024-06-15 01:26:06 发布

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

我有一段代码获取输入并检查输入是否符合要求。输入由名为S的对象组成

class S:
    def __init__(self, f, t, tf, timeline):
        self.f = f
        self.t = t
        self.tf = tf
        self.timeline = timeline

为了知道对象的组合是否满足要求,我让函数取对象大小的list,并返回TrueFalse

input1 = [S_1, ..., S_N]

def c1(input1):
    if condition_c1_valid:
        return True
    else:
        return False

现在让我们来看这个例子:

import itertools

possible_objects = [S(f, t, tf, timeline) for f in [...] for t in [..] ...]
inputs_to_check = list(itertools.combination_with_replacement(possible_objects, 5)

results = list()
for inp in inputs_to_check:
    if c1(inp):
         results.append(inp)

现在,我的解决方案是在每次检查的N条件上使用for循环。 代码保留满足条件的输入

是否可以以矩阵方式立即计算?(矢量化)

我在想这样的事情:(伪代码)

Data[input, c1, ..., cN]
return where(all(c1, ..., cN) is True)

有谁能告诉我这是否可行,并给我举个例子吗?最后,我要检查的输入列表非常大。因此,将计算结果发送到GPU是很有趣的。我想也许这可以通过张量流来实现

谢谢你的提示:)

编辑:上面的例子与现实相去甚远。我在一个大的set上使用嵌套的for循环,复杂度为6级或7级。目前的解决方案是优化发电机,但我想进一步推动这一点


Tags: 对象代码inselffalsetrueforreturn
1条回答
网友
1楼 · 发布于 2024-06-15 01:26:06

在最普遍的意义上,你将无法将其矢量化。由于GIL,CPython在并行处理方面是出了名的糟糕,它的主要矩阵向量化库(numpy)用于处理主要类型(整数、浮点等),而不是python对象,如S

有几件事可以帮上忙:

  1. 如果fttftimeline是数字(它们看起来像 可能是),然后您可以形成这些值的四个numpy数组 通过c1的矢量化版本传递这些值,该版本返回一个布尔数组。然后你可以做np.asarray(input1)[c1_vec(f_vec, t_vec, tf_vec, timeline_vec)]

  2. 您说过您使用了生成器而不是列表,但只是为了确保您的示例应该如下所示:

    possible_objects = (S(f, t, tf, timeline) for f in (...) for t in (...) ...) inputs_to_check = itertools.combination_with_replacement(possible_objects, 5) results = [inp for inp in inputs_to_check if c1(inp)]

    这节省了大量将对象写入内存的时间,这是可以避免的

  3. 使用PyPy。它使用JIT编译器大大加快python for循环的速度。对于非常大的环路,这将达到接近C的速度


你提到使用GPU。CPython甚至不能在一个以上的CPU核上运行,除非使用另一个实现,否则在GPU上运行它是毫无意义的

相关问题 更多 >