首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有效地填充一个多维数组,该数组有许多if else语句

有效地填充一个多维数组,该数组有许多if else语句
EN

Stack Overflow用户
提问于 2016-10-15 18:59:57
回答 3查看 235关注 0票数 3

我想以一种特定和有效的方式填充一个4模糊的numpy数组。因为我不太清楚,所以我用if better语句来编写代码,但这看起来不太好,可能很慢,而且我也不能确定我是否考虑到了每一个组合。下面是我不再写的代码:

代码语言:javascript
复制
sercnew2 = numpy.zeros((gn, gn, gn, gn))
for x1 in range(gn):
    for x2 in range(gn):
        for x3 in range(gn):
            for x4 in range(gn):
                if x1 == x2 == x3 == x4: 
                    sercnew2[x1, x2, x3, x4] = ewp[x1]
                elif x1 == x2 == x3 != x4:
                    sercnew2[x1, x2, x3, x4] = ewp[x1] * ewp[x4]
                elif x1 == x2 == x4 != x3:
                    sercnew2[x1, x2, x3, x4] = ewp[x1] * ewp[x3]
                elif x1 == x3 == x4 != x2:
                    sercnew2[x1, x2, x3, x4] = ewp[x1] * ewp[x2]
                elif x2 == x3 == x4 != x1:
                    sercnew2[x1, x2, x3, x4] = ewp[x2] * ewp[x1]
                elif x1 == x2 != x3 == x4:
                    sercnew2[x1, x2, x3, x4] = ewp[x1] * ewp[x3]
                elif ... many more combinations which have to be considered

因此,应该发生的基本情况是,如果所有变量(x1、x2、x3、x4)彼此不同,条目将是:

代码语言:javascript
复制
sercnew2[x1, x2, x3, x4] = ewp[x1]* ewp[x2] * ewp[x3] * ewp[x4]

现在如果假设变量x2和x4是相同的,那么:

代码语言:javascript
复制
sercnew2[x1, x2, x3, x4] = ewp[x1]* ewp[x2] * ewp[x3]

其他示例可以在上面的代码中看到。基本上,如果两个或多个变量是相同的,那么我只考虑其中的一个。我希望模式是清楚的。否则,请让我注意,我会尽量更好地表达我的问题。我很肯定,有一个更聪明的方法来做这件事。希望你能更好地了解并提前感谢:)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-15 19:37:55

真希望我能得到它!这是一个矢量化的方法-

代码语言:javascript
复制
from itertools import product

n_dims = 4 # Number of dims

# Create 2D array of all possible combinations of X's as rows
idx = np.sort(np.array(list(product(np.arange(gn), repeat=n_dims))),axis=1)

# Get all X's indexed values from ewp array
vals = ewp[idx]

# Set the duplicates along each row as 1s. With the np.prod coming up next,
#these 1s would not affect the result, which is the expected pattern here.
vals[:,1:][idx[:,1:] == idx[:,:-1]] = 1

# Perform product along each row and reshape into multi-dim array
out = vals.prod(1).reshape([gn]*n_dims)
票数 3
EN

Stack Overflow用户

发布于 2016-10-15 19:06:56

我真的不明白你说这些变量是相同的是什么意思,但如果它们确实是相同的,那么你只需要使用set()就行了。

代码语言:javascript
复制
from functools import reduce
from operator import mul
sercnew2 = numpy.zeros((gn, gn, gn, gn))
for x1 in range(gn):
    for x2 in range(x1, gn):
        for x3 in range(x2, gn):
            for x4 in range(x3, gn):
                set_ = [ewp[n] for n in set([x1, x2, x3, x4])]
                sercnew2[x1, x2, x3, x4] = reduce(mul, set_, 1)

它的工作方式是创建一个删除重复项的set(),然后使用reduce函数从set_中选择第一个数字,并将其与1 (初始化器值)相乘,其结果将作为第一个参数传递给reduce,第二个将是set_的第二个条目。抱歉,我解释得不好。

票数 3
EN

Stack Overflow用户

发布于 2016-10-15 19:14:25

您也可以在单个for循环中这样做。在Divakar的索引列表技巧的基础上,我们需要做的第一件事是,如何只提取4d数组sercnew2中给定元素的唯一索引。

最快的方法之一(参见:https://www.peterbe.com/plog/uniqifiers-benchmark)是使用sets。然后,我们只需将sercnew2初始化为一个1数组,而不是0。

代码语言:javascript
复制
from itertools import product
import numpy as np

sercnew2 = np.ones((gn, gn, gn, gn))
n_dims=4
idx = list(product(np.arange(gn), repeat=n_dims))

for i,j,k,l in idx:
    unique_items = set((i,j,k,l))
    for ele in unique_items:
        sercnew2[i,j,k,l] *= ewp[ele]

编辑:正如@unutbu所建议的,我们也可以使用来自https://stackoverflow.com/a/11146645/5714445https://stackoverflow.com/a/11146645/5714445函数来加速idx的初始化

Edit2:如果您很难理解来自itertoolsproduct做了什么,那么它提供了所有的排列。例如,假设gn=2将重复维设置为4,您将得到

代码语言:javascript
复制
[0, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 1, 0]
[0, 0, 1, 1]
[0, 1, 0, 0]
[0, 1, 0, 1]
[0, 1, 1, 0]
[0, 1, 1, 1]
[1, 0, 0, 0]
[1, 0, 0, 1]
[1, 0, 1, 0]
[1, 0, 1, 1]
[1, 1, 0, 0]
[1, 1, 0, 1]
[1, 1, 1, 0]
[1, 1, 1, 1]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40063034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档