mmacheerpuppy - 10 months ago 41

Python Question

I need to do is "crush" the values in l1 by some percentage so they are closer together such that perhaps if an array l1 were ...

`l1 =[10,20,30,40,50,60,70,80,90,100]`

Then l2

`l2 = [12.5, 25.0, 37.5, 50.0, 62.5, 45.0, 52.5, 60.0, 67.5, 75.0]`

That can be done on a simple script such as...

`for i in l1:`

if i <= 50:

i = (i*1.25)

l2.append(i)

print(i)

elif i >= 50:

i = (i*0.75)

l2.append(i)

print (l2)

So that's to indicate I need to bring all the items closer together - ideally by some percentile (printed). The problem occurs when you have a list like this...

`l1 =[4,2,3,4,3,6,4,8.6,10,7,12,4,14,15,26,14,15,16,10]`

What I need to then do is bring all the items together discretely (so by some percentage) but in a loop. I need to "condense" or "crush" the values of the array, reduce the range between each number from smallest to biggest and biggest to smallest (closer to the median). I can't just divide by the whole list since the ranges remain the same.

I thought one way to approach this (what I'm working on now) would be to (a) find the median of l1, (b) start from the smallest and biggest item in l1, increase that item by 10% of it's value or decrease it by 10% of its value (in the case of the biggest item), then work to the second smallest and biggest items in the same loop (to avoid the script going over the same 'smaller variable' twice).

This would mean listing the values from biggest to smallest whilst maintaining their positions in the array (which are important), then searching through that list and making the changes for each corresponding value to the array l1.

For the attention of the proposed solution... One iteration of...

`import statistics`

a = [4, 3, 3, 4, 5, 1, 31, 321]

input_scope = 1.1

def scouter (input_list, scope):

mean = statistics.mean(input_list)

searchpositions = []

for x, i in enumerate(input_list):

print (x, i)

if i == max(input_list) or i == min(input_list):

searchpositions.append(x)

for i in searchpositions:

input_list[i] = [(input_list[i] - mean) / scope + mean]

return (input_list)

print(scouter((a), input_scope))

Gives me what I need, sort of...

`[4, 3, 3, 4, 5, [5.13636363636364], 31, [296.0454545454545]]`

Output is lists in lists! Is there an easy way to eliminate this by re-writing the function?

Answer

Just scale towards the median?

```
>>> l1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
>>> import statistics
>>> median = statistics.median(l1)
>>> [(x - median) / 10 + median for x in l1]
[50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5]
```

Source (Stackoverflow)