在 Jupyter Notebook 上复制 Python 3 (ipykernel) 代码时出现错误“AttributeError: 'NoneType' object has no attribute 'iloc'”

问题描述 投票:0回答:1

从 YouTube 上的定量分析课程中复制一些代码。复制了完全相同的代码,但在我的 Jupyter Notebook 中,弹出了标题中的错误。

from statsmodels.regression.rolling import RollingOLS
import pandas_datareader.data as web
import matplotlib.pyplot as plt
import statsmodels.api as sm
import pandas as pd
import numpy as np
import datetime as dt
import yfinance as yf
import pandas_ta
import warnings
warnings.filterwarnings('ignore')

sp500 = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')[0]

sp500['Symbol'] = sp500['Symbol'].str.replace('.','-')

symbols_list = sp500['Symbol'].unique().tolist()

end_date = '2024-10-9'

start_date = pd.to_datetime(end_date)-pd.DateOffset(365*8)

df = yf.download(tickers=symbols_list,
                  start=start_date,
                  end=end_date).stack()

df.index.names = ['date', 'ticker']

df.columns = df.columns.str.lower()

df['garman_klass_vol'] = ((np.log(df['high'])-np.log(df['low']))**2)/2-(2*np.log(2)-1)*((np.log(df['adj close'])-np.log(df['open']))**2)

df['rsi'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.rsi(close=x, length = 20))

df['bb_low'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.bbands(close=np.log1p(x), length=20).iloc[:,0]

df

错误指的是“pandas_ta.bbands(close=np.log1p(x), length=20).iloc[:,0]”。为什么这个错误只出现在我的电脑上?不同版本?我该如何解决这个问题?

尝试删除该行,其余代码运行得很好,但该表预计没有 bb_low 列。使用版本 Pandas-ta 0.3.14b0 和 Pandas 2.2.3。

pandas group-by jupyter-notebook
1个回答
0
投票

我在可能相同的课程中遇到了同样的问题。错误的原因是一只或多只股票的“调整收盘”价格少于 20 天。这是因为

20
作为
length
传递给
bbands
函数。

如果您使用课程中提供的

end_date
-
2023-09-27
,则不会出现错误。这很可能是因为在 8 年范围内没有新股的数据少于 20 天。

我在下面添加了一些解决方案来解释这种可能性。

准备代码:

sp500 = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')[0]

sp500['Symbol'] = sp500['Symbol'].str.replace('.', '-')

symbols_list = sp500['Symbol'].unique().tolist()

end_date = '2024-08-01'
start_date = pd.to_datetime(end_date) - pd.DateOffset(365*8)

df = yf.download(tickers=symbols_list, start=start_date, end=end_date).stack()

df.index.names = ['date', 'ticker']

df.columns = df.columns.str.lower()

查找不良数据(价格少于20天的股票):

# Check for group sizes
group_sizes = df.groupby(level=1).size()

# Filter groups with size less than the length of the bbands (20)
small_groups = group_sizes[group_sizes < 20]
print("Groups with fewer than 20 rows:\n", small_groups)

解决方案:

  1. 减少 bbands 的
    length

    默认

    length
    是 14,所以你可以这样做。

    df['bb_low'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.bbands(close=np.log1p(x)).iloc[:,0])
    
  2. 删除
    length
    小于20

    的库存
    df = df.groupby(level=1).filter(lambda x: len(x) >= 20)
    df['bb_low'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.bbands(close=np.log1p(x), length=20).iloc[:,0])
    
  3. 如果组中
    NaN
    小于 20,则用
    length
    填充 bbands 结果

    df['bb_low'] = df.groupby(level=1)['adj close'].transform(lambda x: pandas_ta.bbands(close=np.log1p(x), length=20).iloc[:,0] if len(x) >= 20 else np.nan)
    

我不确定理想的解决方案是什么,因为我自己正在学习定量分析,但我选择使用本课程的第三个解决方案。
© www.soinside.com 2019 - 2024. All rights reserved.