Я новичок питон, и я пытаюсь использовать следующий код из этого источника: Portfolio rebalancing with bandwidth method in pythonAttributeError: объект «DataFrame» не имеет атрибута «colmap» в Python
Код хорошо работает до сих пор.
Проблема заключается в том, что если я хочу, чтобы вызвать функцию не как обычно, как rebalance(df, tol)
, но с определенного места в dataframe на, как: rebalance(df[500:], tol)
, я получаю следующее сообщение об ошибке:
AttributeError: 'DataFrame' object has no attribute 'colmap'
. Поэтому мой вопрос: как мне настроить код, чтобы сделать это возможным?
Вот код:
import datetime as DT
import numpy as np
import pandas as pd
import pandas.io.data as PID
def setup_df():
df1 = PID.get_data_yahoo("IBM",
start=DT.datetime(1970, 1, 1),
end=DT.datetime.today())
df1.rename(columns={'Adj Close': 'ibm'}, inplace=True)
df2 = PID.get_data_yahoo("F",
start=DT.datetime(1970, 1, 1),
end=DT.datetime.today())
df2.rename(columns={'Adj Close': 'ford'}, inplace=True)
df = df1.join(df2.ford, how='inner')
df = df[['ibm', 'ford']]
df['sh ibm'] = 0
df['sh ford'] = 0
df['ibm value'] = 0
df['ford value'] = 0
df['ratio'] = 0
# This is useful in conjunction with iloc for referencing column names by
# index number
df.colmap = dict([(col, i) for i,col in enumerate(df.columns)])
return df
def invest(df, i, amount):
"""
Invest amount dollars evenly between ibm and ford
starting at ordinal index i.
This modifies df.
"""
c = df.colmap
halfvalue = amount/2
df.iloc[i:, c['sh ibm']] = halfvalue/df.iloc[i, c['ibm']]
df.iloc[i:, c['sh ford']] = halfvalue/df.iloc[i, c['ford']]
df.iloc[i:, c['ibm value']] = (
df.iloc[i:, c['ibm']] * df.iloc[i:, c['sh ibm']])
df.iloc[i:, c['ford value']] = (
df.iloc[i:, c['ford']] * df.iloc[i:, c['sh ford']])
df.iloc[i:, c['ratio']] = (
df.iloc[i:, c['ibm value']]/df.iloc[i:, c['ford value']])
def rebalance(df, tol):
"""
Rebalance df whenever the ratio falls outside the tolerance range.
This modifies df.
"""
i = 0
amount = 100
c = df.colmap
while True:
invest(df, i, amount)
mask = (df['ratio'] >= 1+tol) | (df['ratio'] <= 1-tol)
# ignore prior locations where the ratio falls outside tol range
mask[:i] = False
try:
# Move i one index past the first index where mask is True
# Note that this means the ratio at i will remain outside tol range
i = np.where(mask)[0][0] + 1
except IndexError:
break
amount = (df.iloc[i, c['ibm value']] + df.iloc[i, c['ford value']])
return df
df = setup_df()
tol = 0.05 #setting the bandwidth tolerance
rebalance(df, tol)
df['portfolio value'] = df['ibm value'] + df['ford value']
df["ibm_weight"] = df['ibm value']/df['portfolio value']
df["ford_weight"] = df['ford value']/df['portfolio value']
print df['ibm_weight'].min()
print df['ibm_weight'].max()
print df['ford_weight'].min()
print df['ford_weight'].max()
# This shows the rows which trigger rebalancing
mask = (df['ratio'] >= 1+tol) | (df['ratio'] <= 1-tol)
print(df.loc[mask])