Перезапуск столбца подсчета при появлении другой строки в Python/Pandas

#python #pandas #function #count #series

Вопрос:

У меня есть следующий фрейм данных Pandas с несколькими суммами для каждого адреса. Количество «сумм» на адрес варьируется.

 Index                                           type    amount
0   0xd81c0B4FEA284c908C5700187a67698b416a6bcc  outflow 2.553800e 04
1   0xd81c0B4FEA284c908C5700187a67698b416a6bcc  inflow  1.999650e 05
2   0xd81c0B4FEA284c908C5700187a67698b416a6bcc  inflow  3.896400e 04
3   0x0A5E7C50eA6BB695F2f4e75D97D3381592B59C9F  inflow  3.060000e 05
4   0x2Eec494429E253938A10b2A9eCAD8ee7F603e4Af  outflow 1.569367e 05
5   0x2Eec494429E253938A10b2A9eCAD8ee7F603e4Af  outflow 1.219739e 04
 

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

Что-то, что выглядело бы так:

 Index                                           type    amount          Epoch
0   0xd81c0B4FEA284c908C5700187a67698b416a6bcc  outflow 2.553800e 04    1
1   0xd81c0B4FEA284c908C5700187a67698b416a6bcc  inflow  1.999650e 05    2
2   0xd81c0B4FEA284c908C5700187a67698b416a6bcc  inflow  3.896400e 04    3
3   0x0A5E7C50eA6BB695F2f4e75D97D3381592B59C9F  inflow  3.060000e 05    1
4   0x2Eec494429E253938A10b2A9eCAD8ee7F603e4Af  outflow 1.569367e 05    1
5   0x2Eec494429E253938A10b2A9eCAD8ee7F603e4Af  outflow 1.219739e 04    2
 

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

Как я могу создать логику для этого столбца для любого заданного количества адресов/строк?

Кроме того: есть ли что-нибудь, на что я должен обратить внимание при структурировании фрейма данных? например, всегда группируйте одинаковые адреса и не допускайте, чтобы они появлялись в случайных местах в фрейме данных.

Комментарии:

1. Должен ли счетчик когда-либо продолжаться для адреса, который появится позже, или он всегда должен начинаться с 1?

2. Да, он должен отслеживать порядок адресов, идущих по строкам, хотя этого, вероятно, никогда не произойдет.

Ответ №1:

Используйте groupby с cumcount :

  1. Если вы хотите, чтобы подсчет продолжался, если адрес повторится позже:
 df["Epoch"] = df.groupby("Index").cumcount() 1

>>> df
                                        Index     type     amount  Epoch
0  0xd81c0B4FEA284c908C5700187a67698b416a6bcc  outflow   25538.00      1
1  0xd81c0B4FEA284c908C5700187a67698b416a6bcc   inflow  199965.00      2
2  0xd81c0B4FEA284c908C5700187a67698b416a6bcc   inflow   38964.00      3
3  0x0A5E7C50eA6BB695F2f4e75D97D3381592B59C9F   inflow  306000.00      1
4  0x2Eec494429E253938A10b2A9eCAD8ee7F603e4Af  outflow  156936.70      1
5  0x2Eec494429E253938A10b2A9eCAD8ee7F603e4Af  outflow   12197.39      2
6  0xd81c0B4FEA284c908C5700187a67698b416a6bcc   inflow  199965.00      4
7  0xd81c0B4FEA284c908C5700187a67698b416a6bcc   inflow   38964.00      5
 
  1. Если вы хотите, чтобы счетчик снова начинался с 1 для адреса, который повторяется:
 df["Epoch"] = df.groupby((df["Index"]!=df["Index"].shift()).cumsum()).cumcount() 1

>>> df
                                        Index     type     amount  Epoch
0  0xd81c0B4FEA284c908C5700187a67698b416a6bcc  outflow   25538.00      1
1  0xd81c0B4FEA284c908C5700187a67698b416a6bcc   inflow  199965.00      2
2  0xd81c0B4FEA284c908C5700187a67698b416a6bcc   inflow   38964.00      3
3  0x0A5E7C50eA6BB695F2f4e75D97D3381592B59C9F   inflow  306000.00      1
4  0x2Eec494429E253938A10b2A9eCAD8ee7F603e4Af  outflow  156936.70      1
5  0x2Eec494429E253938A10b2A9eCAD8ee7F603e4Af  outflow   12197.39      2
6  0xd81c0B4FEA284c908C5700187a67698b416a6bcc   inflow  199965.00      1
7  0xd81c0B4FEA284c908C5700187a67698b416a6bcc   inflow   38964.00      2
 

Обратите внимание на разницу в выводе в последних двух строках. Я скопировал вторую и третью строки вашего примера в конец фрейма данных, чтобы проиллюстрировать разницу в двух методах.

Комментарии:

1. Потрясающе, большое спасибо!