限制列表中的数字&在lis中重新分配多余的数字

2024-10-02 20:36:42 发布

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

我试图用Python编写一个函数,在输入一个最大值时查找一个列表,它将限制列表中的值,并按比例将从该数字中减去的多余值重新分配给列表中的其他数字。你知道吗

例如,我希望通过最大值为0.3的函数传递的[0.05,0.02,0.05,0.08,0.80]为[0.175,0.07,0.175,0.28,0.30]。你知道吗

目前,我在Python中有这样的东西:

''

import numpy as np

x = np.array([0.05, 0.05, 0.02, 0.08, 0.80])
limit = 0.3


excess = 0
y = np.zeros(len(x))
z = np.zeros(len(x))

for i in range(len(x)):
    if x[i] > limit:
        excess = x[i] - limit
        x[i] = 0
        y[i] = limit
        z = x*(1/sum(x)*excess)
        z = z+x+y

''

其中z是这个特定数组的结果。你知道吗

''

z = array([0.175, 0.175, 0.07 , 0.28 , 0.3  ])

''

但是,如果有多个数字超出限制,或者数组的顺序不同,就会出现这种情况。你知道吗


Tags: 函数importnumpy列表lenasnpzeros
1条回答
网友
1楼 · 发布于 2024-10-02 20:36:42

您可以使用以下脚本实现您的目标。这个想法是采取“多余的重量”,并重新分配它对体重不足的元素反复,直到所有的元素已被封顶。这个过程需要重复,因为重新分配可能会使一些原本体重不足的因素超过上限。另外,您没有明确提到它,但是基于finance标签和您的示例,我假设列表的总和需要保持不变。你知道吗

首先,我创建了一个pandas数据帧,其中包含20个值,求和为1,并按降序排列。你知道吗

    Elements    Uncon
3   D   0.081778
1   B   0.079887
19  T   0.079451
17  R   0.070283
11  L   0.068052
4   E   0.057335
12  M   0.054695
5   F   0.051099
6   G   0.049873
18  S   0.049469
14  O   0.045059
16  Q   0.043583
8   I   0.041186
2   C   0.036802
7   H   0.036315
13  N   0.035440
0   A   0.034311
15  P   0.031519
10  K   0.027173
9   J   0.026689

第二,我们把上限设为0.06。这将使它成为您面临的多重超重元素问题的一个很好的测试用例。你知道吗

cap = 0.06
weights = df.Uncon

下面是迭代脚本。你知道吗

# Obtain constrained weights
constrained_wts = np.minimum(cap, weights)
# Locate all stocks with less than max weight
nonmax = constrained_wts.ne(cap)
# Calculate adjustment factor - this is proportional to original weights
adj = ((1 - constrained_wts.sum()) *
        weights.loc[nonmax] / weights.loc[nonmax].sum())
# Apply adjustment to obtain final weights
constrained_wts = constrained_wts.mask(nonmax, weights + adj)
# Repeat process in loop till conditions are satisfied
while ((constrained_wts.sum() < 1) or
       (len(constrained_wts[constrained_wts > cap]) >=1 )):
    # Obtain constrained weights
    constrained_wts = np.minimum(cap, constrained_wts)
    # Locate all stocks with less than max weight
    nonmax = constrained_wts.ne(cap)
    # Calculate adjustment factor - this is proportional to original weights
    adj = ((1 - constrained_wts.sum()) *
        constrained_wts.loc[nonmax] / weights.loc[nonmax].sum())
    # Apply adjustment to obtain final weights
    constrained_wts = constrained_wts.mask(nonmax, constrained_wts + adj)

然后可以将结果重新分配到数据帧并进行比较。你知道吗

df['Cons'] = constrained_wts
 Elements Uncon       Cons
0   A   0.034311    0.039189
1   B   0.079887    0.060000
2   C   0.036802    0.042034
3   D   0.081778    0.060000
4   E   0.057335    0.060000
5   F   0.051099    0.058364
6   G   0.049873    0.056964
7   H   0.036315    0.041478
8   I   0.041186    0.047041
9   J   0.026689    0.030483
10  K   0.027173    0.031037
11  L   0.068052    0.060000
12  M   0.054695    0.060000
13  N   0.035440    0.040479
14  O   0.045059    0.051465
15  P   0.031519    0.036001
16  Q   0.043583    0.049780
17  R   0.070283    0.060000
18  S   0.049469    0.056502
19  T   0.079451    0.060000

元素M是一个很好的例子,说明了为什么需要一个重复的过程。它原本体重不足,但如此接近上限,以至于在第一次重新分配后会变得超重。你知道吗

相关问题 更多 >