生成长度为 7 的数组的总和为 1 的所有组合
Generate all combinations that sum to 1 of array of length 7
我需要找到生成一个数组的最佳方法,该数组包含值 0 到 1.0 的所有可能组合,增量为 0.1,其中每个组合的总和正好等于 1。
我已经使用以下代码为长度为 3 的数组完成了此操作:
portfolios = []
for i in np.arange(0,1.1,0.1):
for j in np.arange(0,1-i,0.1):
k = 1 - i - j
x = [i,j,k]
portfolios.append(x)
portfolios = np.array(portfolios)
这给了我以下内容
print(portfolios)
#Output:
array([[0. , 0. , 1. ],
[0. , 0.1, 0.9],
[0. , 0.2, 0.8],
[0. , 0.3, 0.7],
[0. , 0.4, 0.6],
[0. , 0.5, 0.5],
[0. , 0.6, 0.4],
[0. , 0.7, 0.3],
[0. , 0.8, 0.2],
[0. , 0.9, 0.1],
[0.1, 0. , 0.9],
[0.1, 0.1, 0.8],
[0.1, 0.2, 0.7],
[0.1, 0.3, 0.6],
[0.1, 0.4, 0.5],
[0.1, 0.5, 0.4],
[0.1, 0.6, 0.3],
[0.1, 0.7, 0.2],
[0.1, 0.8, 0.1],
[0.2, 0. , 0.8],
[0.2, 0.1, 0.7],
[0.2, 0.2, 0.6],
[0.2, 0.3, 0.5],
[0.2, 0.4, 0.4],
[0.2, 0.5, 0.3],
...
[0.7, 0. , 0.3],
[0.7, 0.1, 0.2],
[0.7, 0.2, 0.1],
[0.8, 0. , 0.2],
[0.8, 0.1, 0.1],
[0.9, 0. , 0.1]])
但是,我想对长度为 7 的数组执行此操作。也就是说,我想要的输出应该如下所示:
#Desired output
array([[0. , 0., 0., 0., 0., 0., 1.],
[0. , 0., 0., 0., 0., 0.1, 0.9],
[0. , 0., 0., 0., 0., 0.2, 0.8],
...
[0.2, 0.8, 0., 0., 0., 0., 0.],
[0.1, 0.9, 0., 0., 0., 0., 0.],
[.1, 0., 0., 0., 0., 0., 0.]])
有没有一种聪明的方法来扩展我以前的代码?接受所有建议和替代方法。
这是我的尝试。
我在整个代码中添加了注释以帮助解释部分。
此外,最后会输出一个文本文件供您查看结果。
from collections import deque
import numpy as np
import itertools, sys
#We use a recursive approach to get all unique sums to 1.0
def combinations_of_sum(n):
result = []
build_combinations(n, deque(), result)
return result
def build_combinations(sum, combinations, result):
for i in range(sum, 0, -1):
combinations.append(i)
if i == sum:
#print(list(combinations))
adjusted_arr = [n/10 for n in list(combinations)]
result.append(adjusted_arr)
#print(result)
else:
build_combinations(sum-i, combinations, result)
combinations.pop()
#First, we get all the unique lists of sums,
# ...with possibility of repeating numberes
uniques = combinations_of_sum(10)
#Then we filter out based on the array length you want.
#We specify 7 here:
array_length_limit = 7
filtered = []
for unique in uniques:
if len(unique)<=array_length_limit:
filtered.append(unique)
#Now, we fill the filtered arrays with 0s and calculate all
#... permutations, like [0.7,0.3,0.0],[0.7,0.0,0.3], etc.
final = []
for arr in filtered:
padding_length = array_length_limit - len(arr)
arr = arr + [0]*padding_length
permutations = list(set(itertools.permutations(arr,array_length_limit)))
#This is just to show you what's going on
#...You can see the permutations added to the final array.
#print(permutations)
for permutation in permutations:
if list(permutation) not in final:
final.append(list(permutation))
#finally, convert it into a numpy array.
final = np.array(final)
print(final)
np.savetxt('test.out', final, delimiter=',', fmt='%g')
我更改了输出方式,因为项目很多,不方便直接查看。文本文件中的输出如下所示:
由于您想要的所有不同排列,它会持续很长时间。
如果有任何问题以及这是否是您想要的,请告诉我。
我需要找到生成一个数组的最佳方法,该数组包含值 0 到 1.0 的所有可能组合,增量为 0.1,其中每个组合的总和正好等于 1。
我已经使用以下代码为长度为 3 的数组完成了此操作:
portfolios = []
for i in np.arange(0,1.1,0.1):
for j in np.arange(0,1-i,0.1):
k = 1 - i - j
x = [i,j,k]
portfolios.append(x)
portfolios = np.array(portfolios)
这给了我以下内容
print(portfolios)
#Output:
array([[0. , 0. , 1. ],
[0. , 0.1, 0.9],
[0. , 0.2, 0.8],
[0. , 0.3, 0.7],
[0. , 0.4, 0.6],
[0. , 0.5, 0.5],
[0. , 0.6, 0.4],
[0. , 0.7, 0.3],
[0. , 0.8, 0.2],
[0. , 0.9, 0.1],
[0.1, 0. , 0.9],
[0.1, 0.1, 0.8],
[0.1, 0.2, 0.7],
[0.1, 0.3, 0.6],
[0.1, 0.4, 0.5],
[0.1, 0.5, 0.4],
[0.1, 0.6, 0.3],
[0.1, 0.7, 0.2],
[0.1, 0.8, 0.1],
[0.2, 0. , 0.8],
[0.2, 0.1, 0.7],
[0.2, 0.2, 0.6],
[0.2, 0.3, 0.5],
[0.2, 0.4, 0.4],
[0.2, 0.5, 0.3],
...
[0.7, 0. , 0.3],
[0.7, 0.1, 0.2],
[0.7, 0.2, 0.1],
[0.8, 0. , 0.2],
[0.8, 0.1, 0.1],
[0.9, 0. , 0.1]])
但是,我想对长度为 7 的数组执行此操作。也就是说,我想要的输出应该如下所示:
#Desired output
array([[0. , 0., 0., 0., 0., 0., 1.],
[0. , 0., 0., 0., 0., 0.1, 0.9],
[0. , 0., 0., 0., 0., 0.2, 0.8],
...
[0.2, 0.8, 0., 0., 0., 0., 0.],
[0.1, 0.9, 0., 0., 0., 0., 0.],
[.1, 0., 0., 0., 0., 0., 0.]])
有没有一种聪明的方法来扩展我以前的代码?接受所有建议和替代方法。
这是我的尝试。
我在整个代码中添加了注释以帮助解释部分。
此外,最后会输出一个文本文件供您查看结果。
from collections import deque
import numpy as np
import itertools, sys
#We use a recursive approach to get all unique sums to 1.0
def combinations_of_sum(n):
result = []
build_combinations(n, deque(), result)
return result
def build_combinations(sum, combinations, result):
for i in range(sum, 0, -1):
combinations.append(i)
if i == sum:
#print(list(combinations))
adjusted_arr = [n/10 for n in list(combinations)]
result.append(adjusted_arr)
#print(result)
else:
build_combinations(sum-i, combinations, result)
combinations.pop()
#First, we get all the unique lists of sums,
# ...with possibility of repeating numberes
uniques = combinations_of_sum(10)
#Then we filter out based on the array length you want.
#We specify 7 here:
array_length_limit = 7
filtered = []
for unique in uniques:
if len(unique)<=array_length_limit:
filtered.append(unique)
#Now, we fill the filtered arrays with 0s and calculate all
#... permutations, like [0.7,0.3,0.0],[0.7,0.0,0.3], etc.
final = []
for arr in filtered:
padding_length = array_length_limit - len(arr)
arr = arr + [0]*padding_length
permutations = list(set(itertools.permutations(arr,array_length_limit)))
#This is just to show you what's going on
#...You can see the permutations added to the final array.
#print(permutations)
for permutation in permutations:
if list(permutation) not in final:
final.append(list(permutation))
#finally, convert it into a numpy array.
final = np.array(final)
print(final)
np.savetxt('test.out', final, delimiter=',', fmt='%g')
我更改了输出方式,因为项目很多,不方便直接查看。文本文件中的输出如下所示:
由于您想要的所有不同排列,它会持续很长时间。
如果有任何问题以及这是否是您想要的,请告诉我。