首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >组合权重的所有可能组合

组合权重的所有可能组合
EN

Stack Overflow用户
提问于 2014-04-03 14:58:41
回答 2查看 2K关注 0票数 0

我正在寻找更好地在Python中编写以下代码的技巧和技巧(例如删除多余的循环和复制,使用更多的剪接)

我对此进行了编码,为N种证券组合创建了所有可能的加权组合,但必须遵守以下条件:

权重来自一个可能性列表(在本例中为0、.1、.2、.3、.4、.5)有效投资组合的权重之和必须=1(完全投资)

这不是一种有效的方法,因为组合的数量很快就变得难以管理。只是我想掌握这门语言。

谢谢大家的帮助!

代码语言:javascript
复制
import copy as cp

def generateWeights (weights,possibleWeights,N):
    "Generate all possible combinations of weights"
    # cycle over number of desired coloumns
    for i in range(0,N):
        # copy weights to iterate over every element while i pop stuff out of
        # the original list
        weightsCopy = cp.deepcopy(weights)
        for w in weightsCopy:
            # make a copy to edit
            wtemp = cp.deepcopy(w)
            for p in possibleWeights:
                # append every possibility 
                wtemp.append(p)
                # I only want combinations with sum == 1 so I can start
                # avoiding those that are > 1
                if sum(wtemp) <= 1:
                    weights.append(cp.deepcopy(wtemp))
                # get the original wtemp back so I can work on it with my next p
                wtemp.pop()
            # finished developing the first line of the table. Pop it out and
            # move on.
            weights.pop(0)
    # once again copy weights to iterate over every element while I edit the 
    # original list
    weightsCopy = cp.deepcopy(weights)        
    for w in weightsCopy:
        # remove all possibilities whose sum < 1
        # all those > 1 were never added
        if sum(w) < 1:
            weights.remove(w)
    return weights

N=6 # Number of securities
possibleWeights = [0.0,0.1,0.2,0.3,0.4,0.5]
# weights is a coloumn because I want to access its elements and still get
# lists instead of floats.
weights = [[0.0],[0.1],[0.2],[0.3],[0.4],[0.5]]
weights = generateWeights(weights,possibleWeights,N)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-03 15:23:36

您应该使用迭代工具模块,这个模块已经有了算法来完成大部分您想做的事情。

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

def valid_combinations(weights):
    '''generator of possible combinations of weights elements that add up to 1'''
    list_length = len(weights) # we will need this
    for lengths in range(list_length):
        for possible in combinations(weights, lengths): # all possible orderings of weights
            if sum(possible[:lengths]) == 1: # only generate valid ones
                yield possible[:lengths]


>>> original = [0, .1, .2, .3, .4, .5]
>>> print list(valid_combinations(original))
[(0.1, 0.4, 0.5), (0.2, 0.3, 0.5), (0, 0.1, 0.4, 0.5), (0, 0.2, 0.3, 0.5), (0.1, 0.2, 0.3, 0.4), (0, 0.1, 0.2, 0.3, 0.4)]

如果您只对权重的唯一组合感兴趣(顺序并不重要),则需要使用combinations,如果确实重要,则应该以以下方式使用permutations

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

def valid_combinations(weights):
    '''generator of possible combinations of weights elements that add up to 1'''
    list_length = len(weights) # we will need this
    for possible in permutations(weights): # all possible orderings of weights
        for lengths in range(list_length): # get all prefix sublists
            if sum(possible[:lengths]) == 1: # only generate valid ones
                yield possible[:lengths]


>>> original = [0, .1, .2, .3, .4, .5]
>>> print list(valid_combinations(original))
>>> [(0, 0.1, 0.2, 0.3, 0.4), (0, 0.1, 0.2, 0.4, 0.3), (0, 0.1, 0.3, 0.2, 0.4), (0, 0.1, 0.3, 0.4, 0.2), (0, 0.1, 0.4, 0.2, 0.3), (0, 0.1, 0.4, 0.3, 0.2), (0, 0.1, 0.4, 0.5), (0, 0.1, 0.4, 0.5), (0, 0.1, 0.5, 0.4), (0, 0.1, 0.5, 0.4), (0, 0.2, 0.1, 0.3, 0.4), (0, 0.2 ...
票数 2
EN

Stack Overflow用户

发布于 2014-04-03 15:09:33

您可以使用itertools.combinations(),但是必须增加组合的大小,直到达到数据集的长度为止。

代码语言:javascript
复制
>>> input_list = [0,.1,.2,.3,.4,.5]
>>> from itertools import combinations
>>> valid_combinations = []
>>> for comb_length in range(1,len(input_list)+1):
    possible_combinations = combinations(input_list,comb_length)
    for comb in possible_combinations:
        if sum(comb) ==1:
            valid_combinations.append(comb)


>>>valid_combinations
[(0.1, 0.4, 0.5), (0.2, 0.3, 0.5), (0, 0.1, 0.4, 0.5), (0, 0.2, 0.3, 0.5), (0.1, 0.2, 0.3, 0.4), (0, 0.1, 0.2, 0.3, 0.4)]

阅读您的需求,并更新为具有组合==1,而不是<= 1

Note --如果您的输入数据集非常大,您将需要一个更好的算法,因为这是蛮力。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22841469

复制
相关文章

相似问题

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