4

I'm a bit stuck with this one and tried some stuff mentioned here but didn't help. Basically, I've got these arrays:

returns = np.array([0.01, 0.2, 0.05, -0.01, 0.3, -0.5])
weights = np.array([0.3, 0.25, 0.2, 0.15, 0.1, 0])

The idea is to create dynamic weighting in which highest weight matches with highest return. I tried sorting two arrays (or lists) depending on one another but it doesn't help (as mentioned here: Sorting list based on values from another list?), since it really depends on weight initialization.

Desired output would be (weights change their position depending on max/min and in between values of the returns array):

returns = np.array([0.01, 0.2, 0.05, -0.01, 0.3, -0.5])
weights = np.array([0.15, 0.25, 0.2, 0.1, 0.3, 0])

This generally would go row by row through some simple iteration but I cannot seem to crack the problem first. Sorting both separately and then matching ascending / descending order) is no good, since returns array has to be unsorted. Any ideas?

2
  • 1
    Sorry, don't get what you want to do. maybe edit it with an example input, example output and how weights play a role in it? Commented Nov 20, 2020 at 11:46
  • Edited post to mention the desired output Commented Nov 20, 2020 at 11:57

3 Answers 3

2

It looks like you need to use inverse of np.argsort. For simplicity, it could be called ranks. So you can get ranks of returns like so:

_, ranks = np.unique(np.argsort(returns), return_index=True)
>>> ranks
array([2, 4, 3, 1, 5, 0], dtype=int64)

And a remaining part is:

>>> np.sort(weights)[ranks]
array([0.15, 0.25, 0.2 , 0.1 , 0.3 , 0.  ])

Alternative way

Following discussion on similar topic, I found that assignment of inverse argsort could be done also in this way:

a1 = np.argsort(returns)
a2 = np.argsort(weights)
weights[a1] = weights[a2] 
>>> weights
array([0.15, 0.25, 0.2 , 0.1 , 0.3 , 0.  ])
Sign up to request clarification or add additional context in comments.

Comments

1

Check this out:

import numpy as np
returns = np.array([0.01, 0.2, 0.05, -0.01, 0.3, -0.5])
weights = np.array([0.3, 0.25, 0.2, 0.15, 0.1, 0])

temp_dict = dict(zip(sorted(returns), sorted(weights)))

for index, el in enumerate(weights):
    weights[index] = temp_dict[returns[index]]

print(returns)
print(weights)

The output will be:

[ 0.01  0.2   0.05 -0.01  0.3  -0.5 ]
[0.15 0.25 0.2  0.1  0.3  0.  ]

Comments

0

First we find the correct ordering in 'returns' and then we apply this order to the sorted version of 'weights'.

import numpy as np

returns = np.array([0.01, 0.2, 0.05, -0.01, 0.3, -0.5])
weights = np.array([0.3, 0.25, 0.2, 0.15, 0.1, 0])

correctOrderReturns = np.argsort(returns)[::-1] # [4 1 2 0 3 5] Indices of the correct order from max to min in "returns"
sortedWeights = np.sort(weights)[::-1] # [0.3  0.25 0.2  0.15 0.1  0.  ] Ordered list from max to min of weights

for i in range (len(weights)):
    weights[correctOrderReturns[i]] = sortedWeights[i]    

print (returns) #[ 0.01  0.2   0.05 -0.01  0.3  -0.5 ]
print (weights) #[0.15 0.25 0.2  0.1  0.3  0.  ]

This prints the desired output:

Returns: [ 0.01 0.2 0.05 -0.01 0.3 -0.5 ]

Weights: [0.15 0.25 0.2 0.1 0.3 0. ]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.