我想以一种特定和有效的方式填充一个4模糊的numpy数组。因为我不太清楚,所以我用if better语句来编写代码,但这看起来不太好,可能很慢,而且我也不能确定我是否考虑到了每一个组合。下面是我不再写的代码:
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)彼此不同,条目将是:
sercnew2[x1, x2, x3, x4] = ewp[x1]* ewp[x2] * ewp[x3] * ewp[x4]现在如果假设变量x2和x4是相同的,那么:
sercnew2[x1, x2, x3, x4] = ewp[x1]* ewp[x2] * ewp[x3]其他示例可以在上面的代码中看到。基本上,如果两个或多个变量是相同的,那么我只考虑其中的一个。我希望模式是清楚的。否则,请让我注意,我会尽量更好地表达我的问题。我很肯定,有一个更聪明的方法来做这件事。希望你能更好地了解并提前感谢:)
发布于 2016-10-15 19:37:55
真希望我能得到它!这是一个矢量化的方法-
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)发布于 2016-10-15 19:06:56
我真的不明白你说这些变量是相同的是什么意思,但如果它们确实是相同的,那么你只需要使用set()就行了。
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_的第二个条目。抱歉,我解释得不好。
发布于 2016-10-15 19:14:25
您也可以在单个for循环中这样做。在Divakar的索引列表技巧的基础上,我们需要做的第一件事是,如何只提取4d数组sercnew2中给定元素的唯一索引。
最快的方法之一(参见:https://www.peterbe.com/plog/uniqifiers-benchmark)是使用sets。然后,我们只需将sercnew2初始化为一个1数组,而不是0。
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/5714445的https://stackoverflow.com/a/11146645/5714445函数来加速idx的初始化
Edit2:如果您很难理解来自itertools的product做了什么,那么它提供了所有的排列。例如,假设gn=2将重复维设置为4,您将得到
[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]https://stackoverflow.com/questions/40063034
复制相似问题