Вычислить ежедневные доходы с помощью Pandas DataFrame
Вот мой кадр данных Pandas:
prices = pandas.DataFrame([1035.23, 1032.47, 1011.78, 1010.59, 1016.03, 1007.95,
1022.75, 1021.52, 1026.11, 1027.04, 1030.58, 1030.42,
1036.24, 1015.00, 1015.20])
Вот моя функция daily_return
:
def daily_return(prices):
return prices[:-1] / prices[1:] - 1
Вот результат, который исходит от этой функции:
0 NaN
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 NaN
Почему у меня этот вывод?
Ответы
Ответ 1
Поскольку операции будут выполнять выравнивание по индексу, вы можете преобразовать один из DataFrames в массив:
prices[:-1].values / prices[1:] - 1
или
prices[:-1] / prices[1:].values - 1
зависит от того, какой индекс нужного результата вы хотите.
или используйте метод shift()
:
prices.shift(1) / prices - 1
и
prices / prices.shift(1) - 1
Ответ 2
Почему бы не использовать очень удобный pct_change
метод, предоставляемый pandas
по умолчанию:
import pandas as pd
prices = pandas.DataFrame([1035.23, 1032.47, 1011.78, 1010.59, 1016.03, 1007.95,
1022.75, 1021.52, 1026.11, 1027.04, 1030.58, 1030.42,
1036.24, 1015.00, 1015.20])
daily_return = prices.pct_change(1) # 1 for ONE DAY lookback
monthly_return = prices.pct_change(21) # 21 for ONE MONTH lookback
annual_return = prices.pct_change(252) # 252 for ONE YEAR lookback
Оригинал prices
:
print(prices)
0
0 1035.23
1 1032.47
2 1011.78
3 1010.59
4 1016.03
5 1007.95
6 1022.75
7 1021.52
8 1026.11
9 1027.04
10 1030.58
11 1030.42
12 1036.24
13 1015.00
14 1015.20
Daily Return как prices.pct_change(1)
:
print(prices.pct_change(1))
0
0 NaN
1 -0.002666
2 -0.020039
3 -0.001176
4 0.005383
5 -0.007953
6 0.014683
7 -0.001203
8 0.004493
9 0.000906
10 0.003447
11 -0.000155
12 0.005648
13 -0.020497
14 0.000197
Ответ 3
Просто немного дополнения к ответу @YaOzl, и на тот случай, если кто-то прочтет это. Если ваши данные возвращаются в виде таблицы с несколькими акциями:
>>> prices = pandas.DataFrame(
{"StkCode":["StockA","StockA","StockA","StockA","StockA","StockB","StockB","StockB","StockB","StockB","StockC","StockC","StockC","StockC","StockC",],
"Price":[1035.23, 1032.47, 1011.78, 1010.59, 1016.03, 1007.95, 1022.75, 1021.52, 1026.11, 1027.04, 1030.58, 1030.42, 1036.24, 1015.00, 1015.20]}
)
Что дает вам:
Price StkCode
0 1035.23 StockA
1 1032.47 StockA
2 1011.78 StockA
3 1010.59 StockA
4 1016.03 StockA
5 1007.95 StockB
6 1022.75 StockB
7 1021.52 StockB
8 1026.11 StockB
9 1027.04 StockB
10 1030.58 StockC
11 1030.42 StockC
12 1036.24 StockC
13 1015.00 StockC
14 1015.20 StockC
Тогда вы можете просто совместно использовать .pct_change (k) с .groupby(StkCode). И это в разы быстрее, чем при использовании итератора... (Я попробовал свой набор данных, успешно сократил время процесса с 10 часов до 20 секунд !!)
>>> prices["Return"] = prices.groupby("StkCode")["Price"].pct_change(1)
Дает тебе:
Price StkCode Return
0 1035.23 StockA NaN
1 1032.47 StockA -0.002666
2 1011.78 StockA -0.020039
3 1010.59 StockA -0.001176
4 1016.03 StockA 0.005383
5 1007.95 StockB NaN
6 1022.75 StockB 0.014683
7 1021.52 StockB -0.001203
8 1026.11 StockB 0.004493
9 1027.04 StockB 0.000906
10 1030.58 StockC NaN
11 1030.42 StockC -0.000155
12 1036.24 StockC 0.005648
13 1015.00 StockC -0.020497
14 1015.20 StockC 0.000197