Уведомления

Группа в Telegram: @pythonsu

#1 Май 29, 2014 15:28:58

jagg
Зарегистрирован: 2014-05-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

Изучаю 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 (Май 29, 2014 15:34:33)

Офлайн

#2 Май 29, 2014 17:09:04

jagg
Зарегистрирован: 2014-05-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

смотрел в сторону numpy.linalg
но из распределений там только линейные или нормальные (по гауссиане)

Офлайн

#3 Май 29, 2014 21:10:11

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

jagg
решение должно универсальным, то есть не быть независимым от количества групп
Есть один мощный метод:
for i,j in zip(M,N):
    ....



Офлайн

#4 Май 29, 2014 22:56:19

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

>>> 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))
>>>



Офлайн

#5 Май 30, 2014 08:34:53

jagg
Зарегистрирован: 2014-05-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

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 (Май 30, 2014 08:39:48)

Офлайн

#6 Май 30, 2014 08:53:16

jagg
Зарегистрирован: 2014-05-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

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.])]

Отредактировано jagg (Май 30, 2014 08:59:33)

Офлайн

#7 Май 30, 2014 09:12:17

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

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)]
>>>



Отредактировано py.user.next (Май 30, 2014 09:14:43)

Офлайн

#8 Май 30, 2014 09:17:37

jagg
Зарегистрирован: 2014-05-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

py.user.next
map(f, mlst, nlst)
заработало! спасибо.

Офлайн

#9 Май 30, 2014 10:04:57

jagg
Зарегистрирован: 2014-05-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

краткое резюме:
погонял оба варианта
НАИБОЛЕЕ быстрым является вариант, с использованием map(f, m, n),
что ожидаемо .

еще раз всем спасибо.

Офлайн

#10 Май 30, 2014 11:56:12

jagg
Зарегистрирован: 2014-05-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Пропорциональное распределение в массиве

конечное решение, с проверкой деления на 0

lambda asource, atarget: map (lambda n, arr: n * (arr / np.sum(arr)) if np.sum(arr)<>0 else (arr) * 0, asource, atarget)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version