Разделите сумму по строкам - PullRequest
4 голосов
/ 17 января 2020

Я хотел бы разделить определенное количество элементов на несколько строк. Каждая строка должна получить как минимум 1, а остальные в соответствии с их необходимой долей, пока все элементы не будут распределены. Допустим, у нас есть 6 доступных, я хотел бы получить результат следующим образом.

Использование max(1, factor * available) не обязательно составляет общее количество доступных предметов.

Есть ли прочь? У меня есть данные в искровой среде, поэтому самым классным методом будет решение pyspark или даже pandas / numpy. Это довольно легко сделать за python l oop. Очевидно.

Ввод: Всего доступно 6

+---+-------------+
| c1|       factor|
+---+-------------+
|  A|        0.001|
|  B|          0.2|
|  C|          0.2|
|  D|          0.2|
|  E|          0.3|
+---+-------------+

Ожидаемый результат:

+---+-------------+---------+
| c1|       factor|   result|
+---+-------------+---------+
|  A|        0.001|        1|
|  B|          0.2|        1|
|  C|          0.2|        1|
|  D|          0.2|        1|
|  E|          0.3|        2|
+---+-------------+---------+

Ответы [ 2 ]

1 голос
/ 17 января 2020

Вот как я бы подошел к проблеме, если я правильно ее понял:

import numpy as np
import pandas as pd 

data = {'c1':['A','B','C','D','E'],'factor':[0.001,0.2,0.2,0.2,0.3]}
df = pd.DataFrame(data)
df['factor_rescaled'] = df['factor'] / df['factor'].sum()
available = int(input('Available = '))
df['result'] = np.where(round(df['factor_rescaled']*available,0) < 1,1,round(df['factor_rescaled']*available,0))
print(df)

Передача значения 6 дает следующий результат:

  c1  factor  factor_rescaled  result
0  A   0.001         0.001110     1.0
1  B   0.200         0.221976     1.0
2  C   0.200         0.221976     1.0
3  D   0.200         0.221976     1.0
4  E   0.300         0.332963     2.0

Изменение масштаба выполнено чтобы убедиться, что если факторы слишком высоки или низки, значение available полностью распределено и не перераспределено. Наконец, я не уверен, откуда взялась эта цифра available, поэтому я просто поместил ее в качестве ввода, например, 6.

Окончательное редактирование: использование np.where из-за Почему np.where быстрее, чем pd.apply

0 голосов
/ 17 января 2020

Вы можете сделать это, используя pandas:

>>> df
  c1  factor
0  A   0.001
1  B   0.200
2  C   0.200
3  D   0.200
4  E   0.300
>>> available, s = 6, df.factor.sum()
>>> df['result'] = df.factor.apply(lambda x: round(max(1, (x/s)*available)))
>>> df
  c1  factor  result
0  A   0.001     1.0
1  B   0.200     1.0
2  C   0.200     1.0
3  D   0.200     1.0
4  E   0.300     2.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...