2016-11-22 3 views
3

Извините, если этот вопрос уже задан, но заблаговременно за вашу помощь.Pandas суммарная сумма частичных элементов с groupby

В этом "unpivoted" набор данных, есть Заказов, состоящие из нескольких Многих. Каждый Лот имеет заданное значение точки, как показано ниже:

CustID  Date   OrderNum LotNum PtsPerLot 
A123  1/1/2015  1234  A  2    
A123  1/1/2015  1234  B  10 
A123  1/1/2015  5678  A  7 

Моя цель состоит в том, чтобы создать CUMULATIVE_POINTS_PER_YEAR столбец, представляющий собой кумулятивную сумму POINTS_PER_ORDER, которая сама по себе сумму PtsPerLot, на каждом Lot уровне. Таким образом, для данного лота CumPtsPerYear покажет совокупную сумму всего POINTS_PER_ORDER для учетной записи в данном году.

CustID  Date   OrderNum LotNum PtsPerLot *PtsPerOrder* *CumPtsPerYear* 
A123  1/1/2015  1234  A  2   12    12 
A123  1/1/2015  1234  B  10   12    12 
A123  1/1/2015  5678  A  7   7    19 

Любые идеи? Я пробовал groupby.cumsum на PtsPerLot и еще groupby.cumsum на PtsPerOrder, но он не производит то, что мне нужно.

+0

Как CumPtsPerYear суммарная сумма PtsPerOrder? –

+0

Заказ № 1234, между двумя лотами, суммы до 12 баллов. – user791411

+0

Правильно, но суммарная сумма PtsPerOrder будет 12, 24, 31 ... –

ответ

1

Во-первых, рассчитать PtsPerOrder. Используйте transform для трансляции по фактическому индексу вашего dataframe результата вычисления в каждой группе:

df['PtsPerOrder'] = df.groupby('OrderNum')['PtsPerLot'].transform(sum) 

Затем возьмите первый элемент этого нового столбца в каждой группе:

df['CumPtsPerYear'] = df.groupby('OrderNum')['PtsPerOrder'].head(1) 

df 
Out[27]: 
    CustID  Date OrderNum LotNum PtsPerLot PtsPerOrder CumPtsPerYear 
0 A123 1/1/2015  1234  A   2   12   12.0 
1 A123 1/1/2015  1234  B   10   12   NaN 
2 A123 1/1/2015  5678  A   7   7   7.0 

End расчет путем выполнения суммарной суммы, которую вы ищете. Он пропустит значения NA. Вы заполняете свой фрейм с форвардным заполнением:

df['CumPtsPerYear'].cumsum().ffill() 

0 12.0 
1 12.0 
2 19.0 
+0

Спасибо! Это делает этот трюк! – user791411

+0

* это * имеет смысл. –

+0

Нет, это должно было быть для @ user791411, на самом деле. Я не мог понять спецификации, но когда я вижу это в «пандах», это имеет смысл сейчас. Я смущался о лотах и ​​ordernums. Не понял, что это были вы! Я не думал, что ваш другой ответ не имеет смысла, это просто предложение для разработки. –

0

Чтобы получить первую часть вашего вопроса, PtsPerOrder, вам необходимо преобразование . sum - это агрегация. Так что используйте .transform:

In [10]: df 
Out[10]: 
      Date OrderNum LotNum PtsPerLot 
CustID 
A123 1/1/2015  1234  A   2 
A123 1/1/2015  1234  B   10 
A123 1/1/2015  5678  A   7 

In [11]: df.groupby('OrderNum')['PtsPerLot'].transform('sum') 
Out[11]: 
CustID 
A123 12 
A123 12 
A123  7 
dtype: int64 

и использовать, чтобы создать новый столбец ...

In [13]: df['PtsPerOrder'] = df.groupby('OrderNum')['PtsPerLot'].transform('sum') 

In [14]: df 
Out[14]: 
      Date OrderNum LotNum PtsPerLot PtsPerOrder 
CustID 
A123 1/1/2015  1234  A   2   12 
A123 1/1/2015  1234  B   10   12 
A123 1/1/2015  5678  A   7   7 

Я до сих пор не grokking спецификацию для CumPtsPerYear ...

+0

Спасибо за помощь! В этом случае, поскольку в указанном порядке (как в столбце) есть 12 суммарных точек и 7 суммарных точек в следующем порядке, 'CumPtsPerYear' будет 12, 19. – user791411

+0

@ user791411 вы случайно меня понизили? –

+0

Странно нет, но я просто поддержал вас! – user791411

1

Прежде всего, необходимо использовать transformation:

df['*PtsPerOrder*'] = df.groupby('OrderNum')['PtsPerLot'].transform(sum) 

Тогда для того, чтобы создать другую, я не фи й еще один способ, который, чтобы найти максимум из каждой группы, сделать cumsum на что, и объединить, что еще в:

weird_cumsum = df.groupby('OrderNum')['*PtsPerOrder*'].max().cumsum().to_frame() 
weird_cumsum.columns = ['*CumPtsPerYear*'] 
weird_cumsum 

      *CumPtsPerYear* 
OrderNum     
1234     12 
5678     19 

df.merge(weird_cumsum, left_on='OrderNum', right_index=True, how='left') 

Результат такой, как ожидалось:

CustID  Date OrderNum LotNum PtsPerLot *PtsPerOrder* *CumPtsPerYear* 
0 A123 2015-01-01  1234  A   2    12    12 
1 A123 2015-01-01  1234  B   10    12    12 
2 A123 2015-01-01  5678  A   7    7    19 
Смежные вопросы