#python #pandas
Вопрос:
Я столкнулся со следующей проблемой:
Для каждой строки в кадре данных я хотел бы вычислить тип скалярного произведения двух столбцов со следующими правилами:
- для строк ниже и включая текущую строку (индекс <= текущий индекс), вычислите скалярное произведение столбцов
value
иmultiplier
. - для строк, расположенных выше текущей строки (индекс > текущий индекс), возьмите сумму >
value
(-> >multiplier
= 1) - суммируйте обе суммы.
Позвольте мне проиллюстрировать это. Вот некоторый код для создания фрейма данных для начала:
import pandas as pd
if __name__ == "__main__":
df = pd.DataFrame({'value': list(range(1, 11, 1))})*10
limit = 50
df['multiplier'] = 1 (df['value']<limit)*0.666
К чему я хочу подойти, так это к следующему:
Index value multiplier Total
0 1 10 1.667 556.7
1 2 20 1.667 570.0
2 3 30 1.667 590.0
3 4 40 1.667 616.7
4 5 50 1.000 616.7
5 6 60 1.000 616.7
6 7 70 1.000 616.7
7 8 80 1.000 616.7
8 9 90 1.000 616.7
9 10 100 1.000 616.7
Для первого ряда- Total
это 10 * 1.667 scalarproduct([20, 30, 40, ..., 100} * [1]*9) = 16.67 540 = 556.67
. (второй ряд: [10, 20]*[1.667]*2 [30, 40, ..., 100]*[1]*8
и т. Д.).
Веса вычисляются соответственно, и weighted avarage
разделяются только два столбца.
Я подозреваю, что это было бы достижимо с использованием pandas.api.indexers
библиотеки, но я не уверен, с чего начать.
Любая помощь будет очень признательна!
Комментарии:
1. Непонятно, как
Weight
рассчитывается
Ответ №1:
Чтобы получить Total
столбец, вы можете создать функцию для реализации вычислений и применить ее axis=1
. Для Index
столбца вы можете просто добавить 1 к индексу фрейма данных и назначить его:
def funcTotal(row, df):
mask = df.index<=row.name
lower = (df[mask]['value']*df[mask]['multiplier']).sum()
upper = (df[~mask]['value']).sum()
return lower upper
df['Total'] = df.apply(lambda x:funcTotal(x, df), axis=1)
df['Index'] = df.index 1
выход
value multiplier Total Index
0 10 1.666 556.66 1
1 20 1.666 569.98 2
2 30 1.666 589.96 3
3 40 1.666 616.60 4
4 50 1.000 616.60 5
5 60 1.000 616.60 6
6 70 1.000 616.60 7
7 80 1.000 616.60 8
8 90 1.000 616.60 9
9 100 1.000 616.60 10
Комментарии:
1. Привет всем — большое спасибо! Похоже, я был на неправильном пути здесь, ища решение с расширением окон. Я исправлю голосование «против», как только смогу, я нажал не на ту кнопку на своем телефоне.