#python #pandas
#python #pandas
Вопрос:
У меня есть фрейм данных, подобный
pd.DataFrame({'i': [ 3, 4, 12, 25, 44, 45, 52, 53, 65, 66]
, 't': range(1,11)
, 'v': range(0,100)[::10]}
)
т.е.
i t v
0 3 1 0
1 4 2 10
2 12 3 20
3 25 4 30
4 44 5 40
5 45 6 50
6 52 7 60
7 53 8 70
8 65 9 80
9 66 10 90
Я хотел бы суммировать значения в столбце v
со следующим столбцом, если i
они увеличены на 1, в противном случае ничего не делайте.
Можно предположить, что для суммирования существует максимум две последовательные строки, поэтому последняя строка может быть неоднозначной, в зависимости от того, суммируется она или нет.
Результирующий фрейм данных должен выглядеть следующим образом:
i t v
0 3 1 10
2 12 3 20
3 25 4 30
4 44 5 90
6 52 7 130
8 65 9 170
Очевидно, что я мог бы перебирать фрейм данных, используя .iterrows()
, но должно быть более разумное решение.
Я пробовал различные комбинации shift
, diff
и groupby
, хотя я не вижу, как это сделать…
Ответ №1:
Это обычный метод идентификации блока с помощью cumsum в diff:
blocks = df['i'].diff().ne(1).cumsum()
df.groupby(blocks, as_index=False).agg({'i':'first','t':'first', 'v':'sum'})
Вывод:
i t v
0 3 1 10
1 12 3 20
2 25 4 30
3 44 5 90
4 52 7 130
5 65 9 170
Ответ №2:
Давайте попробуем
out = df.groupby(df['i'].diff().ne(1).cumsum()).agg({'i':'first','t':'first','v':'sum'})
Out[11]:
i t v
i
1 3 1 10
2 12 3 20
3 25 4 30
4 44 5 90
5 52 7 130
6 65 9 170