Найти - Пользователи
Полная версия: Пропорциональное распределение в массиве
Начало » Python для новичков » Пропорциональное распределение в массиве
1
jagg
Изучаю numpy
.
Решил написать программу распределения некоторого числа по элементам массива, состоящего из чисел, пропорционально его числовым значениям.

Задача 1
у нас есть одномерный массив состоящий из 5-ти элементов 20, 25, 30, 22, 33
и есть число 70, которое мы должны распределить

для решения данной задачи хорошо подходит numpy
и я написал следующий скрипт:
import numpy as np
vG = 70.
mL = np.array([20, 25, 30, 22, 33 ], np.float)
print (mL)
vA = np.sum(mL)
print (vA)
mP = vG * mL / vA
print (mP)
print (np.sum(mP))

Задача 2
у нас есть массив массивов M ((20, 25, 30, 22, 33), (40, 10, 35), (10, 30, 20, 15 ) )
и одномерный массив чисел N (70, 50, 60), которые необходимо распределить на элементы массива M следующим образом N0 на M0, N1 M1 и N2 на M2

решение должно универсальным, то есть не быть независимым от количества групп
Что посоветуете использовать? может есть специализированные функции из numpy?
jagg
смотрел в сторону numpy.linalg
но из распределений там только линейные или нормальные (по гауссиане)
doza_and
jagg
решение должно универсальным, то есть не быть независимым от количества групп
Есть один мощный метод:
for i,j in zip(M,N):
    ....
py.user.next
>>> def f(arr, n):
...     k = n / sum(arr)
...     return tuple(k * i for i in arr)
... 
>>> mlst = ((20, 25, 30, 22, 33), (40, 10, 35), (10, 30, 20, 15))
>>> nlst = (70, 50, 60)
>>> 
>>> tuple(map(f, mlst, nlst))
((10.769230769230768, 13.461538461538462, 16.153846153846153, 11.846153846153845, 17.76923076923077), (23.529411764705884, 5.882352941176471, 20.58823529411765), (8.0, 24.0, 16.0, 12.0))
>>>
jagg
doza_and

большое спасибо за идею!

сделал так
>>> mB = np.array ([70., 50., 60.])
>>> mL = np.array ([ [20., 25., 30., 22., 33.], [40., 10., 35.], [10., 30., 20., 15.] ])
>>> def f_sum (n, m):
...     import numpy as np
...     return np.array (tuple (i * (j / np.sum(j)) for i, j in zip(n, m)))
... 
>>> x = f_sum (mB, mL)
>>> print (x)
[ array([ 10.76923077,  13.46153846,  16.15384615,  11.84615385,  17.76923077])
 array([ 23.52941176,   5.88235294,  20.58823529])
 array([  8.,  24.,  16.,  12.])]

следует обратить внимание, на строку
i * (j / np.sum(j)) for i, j in zip(n, m)
сначала я написал i * j / np.sum (j), что привело к перемножению массивов и потом уже делению внутри массива, поэтому пришлось явно указать, на порядок действий, сначала вычисляем коэффициенты (j / np.sum(j)), а затем уже умножаем их на элемент массива i.
jagg
py.user.next

красивый ход, но у меня не пошло - результат не тот

>>> def f(arr, n):
...     k = n / sum(arr)
...     return tuple(k * i for i in arr)
... 
>>> mlst = ((20, 25, 30, 22, 33), (40, 10, 35), (10, 30, 20, 15))
>>> nlst = (70, 50, 60)
>>> 
>>> tuple(map(f, mlst, nlst))
((0, 0, 0, 0, 0), (0, 0, 0), (0, 0, 0, 0))

у меня получилось так:

>>> import numpy as np
>>> 
>>> narray = np.array ([70., 50., 60.])
>>> marray = np.array ([ [20., 25., 30., 22., 33.], [40., 10., 35.], [10., 30., 20., 15.] ])
>>> 
>>> def f(arr, n):
...     return (n * (arr / np.sum(arr)))
... 
>>> map(f, marray, narray)
[array([ 10.76923077,  13.46153846,  16.15384615,  11.84615385,  17.76923077]), array([ 23.52941176,   5.88235294,  20.58823529]), array([  8.,  24.,  16.,  12.])]
py.user.next
jagg
но у меня не пошло

>>> def f(arr, n):
...     k = float(n) / sum(arr)
...     return tuple(k * i for i in arr)
... 
>>> mlst = ((20, 25, 30, 22, 33), (40, 10, 35), (10, 30, 20, 15))
>>> nlst = (70, 50, 60)
>>> 
>>> map(f, mlst, nlst)
[(10.769230769230768, 13.461538461538462, 16.153846153846153, 11.846153846153845, 17.76923076923077), (23.529411764705884, 5.882352941176471, 20.58823529411765), (8.0, 24.0, 16.0, 12.0)]
>>>
jagg
py.user.next
map(f, mlst, nlst)
заработало! спасибо.
jagg
краткое резюме:
погонял оба варианта
НАИБОЛЕЕ быстрым является вариант, с использованием map(f, m, n),
что ожидаемо .

еще раз всем спасибо.
jagg
конечное решение, с проверкой деления на 0
lambda asource, atarget: map (lambda n, arr: n * (arr / np.sum(arr)) if np.sum(arr)<>0 else (arr) * 0, asource, atarget)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB