#python #pandas #dataframe
#python #pandas #фрейм данных
Вопрос:
daychange SS
0.017065 0
-0.009259 100
0.031542 0
-0.004530 0
0.000709 0
0.004970 100
-0.021900 0
0.003611 0
У меня есть два столбца, и я хочу вычислить сумму следующих 5 ‘daychange’, если SS = 100.
Сейчас я использую следующее, но оно работает не совсем так, как я хочу:
df['total'] = df.loc[df['SS'] == 100,['daychange']].sum(axis=1)
Комментарии:
1. Каков ваш ожидаемый результат для ваших данных примера?
2. Это должно быть около 0,0236
3. Вы не хотите
sum
, чтобы для второго100
вSS
?4. Я делаю. Для второго ‘SS = 100’ мне нужна сумма следующих 5 ‘daychange’. Например (0.0049 — 0.0219 0.0036 …). Я надеюсь, что в моих словах есть смысл
Ответ №1:
Поскольку pandas 1.1
вы можете создать окно прокрутки вперед и выбрать строки, которые вы хотите включить в свой фрейм данных. С разными аргументами ядро моего ноутбука было прекращено: используйте с осторожностью.
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=5)
df['total'] = df.daychange.rolling(indexer, min_periods=1).sum()[df.SS == 100]
df
Out:
daychange SS total
0 0.017065 0 NaN
1 -0.009259 100 0.023432
2 0.031542 0 NaN
3 -0.004530 0 NaN
4 0.000709 0 NaN
5 0.004970 100 -0.013319
6 -0.021900 0 NaN
7 0.003611 0 NaN
Исключить начальную строку с SS == 100
из суммы
Это будет следующая строка после строк с SS == 100
. Поскольку все строки вычисляются, вы можете использовать
df['total'] = df.daychange.rolling(indexer, min_periods=1).sum().shift(-1)[df.SS == 100]
df
Out:
daychange SS total
0 0.017065 0 NaN
1 -0.009259 100 0.010791
2 0.031542 0 NaN
3 -0.004530 0 NaN
4 0.000709 0 NaN
5 0.004970 100 -0.018289
6 -0.021900 0 NaN
7 0.003611 0 NaN
Медленное хакерское решение с использованием индексов выбранных строк
Это похоже на взлом, но работает и позволяет избежать вычисления ненужных скользящих значений
df['next5sum'] = df[df.SS == 100].index.to_series().apply(lambda x: df.daychange.iloc[x: x 5].sum())
df
Out:
daychange SS next5sum
0 0.017065 0 NaN
1 -0.009259 100 0.023432
2 0.031542 0 NaN
3 -0.004530 0 NaN
4 0.000709 0 NaN
5 0.004970 100 -0.013319
6 -0.021900 0 NaN
7 0.003611 0 NaN
Для суммы следующих пяти строк, исключая строки с SS == 100
, вы можете настроить срезы или сдвинуть ряд
df['next5sum'] = df[df.SS == 100].index.to_series().apply(lambda x: df.daychange.iloc[x 1: x 6].sum())
# df['next5sum'] = df[df.SS == 100].index.to_series().apply(lambda x: df.daychange.shift(-1).iloc[x: x 5].sum())
df
Out:
daychange SS next5sum
0 0.017065 0 NaN
1 -0.009259 100 0.010791
2 0.031542 0 NaN
3 -0.004530 0 NaN
4 0.000709 0 NaN
5 0.004970 100 -0.018289
6 -0.021900 0 NaN
7 0.003611 0 NaN
7 0.003611 0 NaN
Комментарии:
1. Интересный подход! Хотя кажется
.rolling()
, что работает намного быстрее. Например, когда я реплицирую и объединяю данные примераdf = pd.concat([df for i in range(1000)]).reset_index(drop=True)
, этот подход потребовал почти в 100 раз больше по сравнению сrolling
предыдущим. Эта разница еще больше с большим количеством строк в данных.2. Большое спасибо за ответ. Можете ли вы помочь с немного другой проблемой: как я могу взять сумму следующих 5 чисел на этот раз, не включая строку, где SS = 100. Например, вместо суммы строк 1-5 я беру сумму строк 2-6
3. @Ramsey — добавил это требование к моему ответу.
4. Большое спасибо. Однако, если я хочу использовать «хакерское» решение, я полагаю, мне нужно добавить .shift(-1), но в каком месте?
5. Но для более быстрого метода он выдает ошибку abt «api.indexer», что он не найден.