Pandas Groupby лямбда-функция несколько условий / столбцы - PullRequest
0 голосов
/ 31 октября 2018

Я пытаюсь создать новый столбец, который группирует df по Deal и Month и применяет процент (9%) к столбцу Amount. Если все значения Amount для определенного Deal в конкретном месяце составляют в сумме до 20 000, тогда примените процент к Amount; в противном случае, если TYPE равно MONTHLY, а индивидуальное Amount равно не менее 1500, примените процент к Amount; в противном случае умножьте на 0.

df.groupby(['Deal', 'Month'])["Amount"].apply(
    lambda x: x.sum() * 0.09 if x.sum() >= 20000 else (
        x * 0.09 if x >= 1500 and x['TYPE'] == 'MONTHLY' else 0
    )
)

Это то, что я пытался, но продолжаю получать ошибки, такие как ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). ИЛИ KeyError: ('TYPE', u'occurred at index 0') и т. Д. Я пытался использовать преобразование вместо применения тоже. Буду очень признателен за любую помощь.

Это если то, на что похож мой сгруппированный DF + Желаемый столбец

   Deal         TYPE    Month        Amount   Desired Column
0   Com A   ANNUAL  April   10021.34   0
1   Com A   MONTHLY April   35.86 .    0
2   Com B   MONTHLY April   11150.05   1,003.50
3   Com B   ANNUAL  July    661.65     0
4   Com B   ANNUAL  August  303.63     0
5   Com C   ANNUAL  April   25624.59   2,306.21
6   Com D   ANNUAL  June    27309.26   2,457.83  
7   Com D   ANNUAL  July    0.00       0
8   Com D   ANNUAL  August  0.00       0
9   Com E   ANNUAL  April   10.65      0
10  Com E   MONTHLY May     0.00       0
11  Com E   ANNUAL  May     18716.70   1,684.5
12  Com E   MONTHLY June    0.00       0
13  Com E   ANNUAL  June    606.49     0
14  Com E   MONTHLY July    0.00       0
15  Com E   MONTHLY July    8890.17    800.11
16  Com E   MONTHLY August  4000       0
17  Com E   ANNUAL  August  16000      1,800
18  Com E   ANNUAL  September 2157.34  0
19  Com E   ANNUAL  October 3025.24    0

DF

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Я пытался перевести ваше описание в это:

df['Sum'] = df.groupby(['Deal','Month'])['Amount'].transform('sum')

df['Desired Column'] = np.where(df['Sum'] > 20000, df['Sum'] * 0.09, np.where((df['Amount'] >= 1500) & (df['TYPE'] == 'MONTHLY'), df['Amount'] * 0.09, 0))

Хотя я обнаружил некоторые различия между сгенерированным мной результатом и "желаемым столбцом", который вы опубликовали, например, в строке 16, это ежемесячно и имеет сумму больше 1500, поэтому результат должен был быть 0,09 * 4000 = 360, не знаю, как вы получили 0. Я думаю, вы либо ошиблись во время ручного расчета, либо, возможно, я неправильно понял ваше описание, пожалуйста не стесняйтесь объяснять это чтобы я мог обновить свой сценарий, но я думаю, что общая идея должна была решить вашу проблему.

P.S. результат df после запуска моего скрипта

   Deal     TYPE      Month    Amount       Sum  Desired Column
0     A   ANNUAL      April  10021.34  10057.20          0.0000
1     A  MONTHLY      April     35.86  10057.20          0.0000
2     B  MONTHLY      April  11150.05  11150.05       1003.5045
3     B   ANNUAL       July    661.65    661.65          0.0000
4     B   ANNUAL     August    303.63    303.63          0.0000
5     C   ANNUAL      April  25624.59  25624.59       2306.2131
6     D   ANNUAL       June  27309.26  27309.26       2457.8334
7     D   ANNUAL       July      0.00      0.00          0.0000
8     D   ANNUAL     August      0.00      0.00          0.0000
9     E   ANNUAL      April     10.65     10.65          0.0000
10    E  MONTHLY        May      0.00  18716.70          0.0000
11    E   ANNUAL        May  18716.70  18716.70          0.0000
12    E  MONTHLY       June      0.00    606.49          0.0000
13    E   ANNUAL       June    606.49    606.49          0.0000
14    E  MONTHLY       July      0.00   8890.17          0.0000
15    E  MONTHLY       July   8890.17   8890.17        800.1153
16    E  MONTHLY     August   4000.00  18000.00        360.0000
17    E   ANNUAL     August  14000.00  18000.00          0.0000
18    E   ANNUAL  September   2157.34   2157.34          0.0000
19    E   ANNUAL    October   3025.24   3025.24          0.0000
0 голосов
/ 31 октября 2018

Вам не нужно groupby в этом случае. Есть несколько способов сделать это, концептуально проще всего сначала рассчитать пороговое значение на основе того, является ли это месячной или годовой суммой

df['Threshold'] = (df.TYPE=='ANNUAL')*20000 + (df.TYPE=='MONTHLY')*1500

Затем вы можете рассчитать сумму на основе того, был ли достигнут порог

df['Desired Amount'] = (df.Amount>df.Threshold)*0.09*df.Amount

Но это работает здесь, потому что у вас нет нескольких строк для одной и той же сделки, месяца и типа. Если бы вы это сделали, вам сначала нужно было бы сгруппировать данные по всем этим

df = df.groupby(['Deal','Month','TYPE']).sum()
df.reset_index(inplace=True)

Тогда вы можете продолжить, как указано выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...