Вперед и назад, глядя на расширяющееся окно, вычисляется среднее значение

#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. Привет всем — большое спасибо! Похоже, я был на неправильном пути здесь, ища решение с расширением окон. Я исправлю голосование «против», как только смогу, я нажал не на ту кнопку на своем телефоне.