在《Python for Data Analysis》的第五章 Pandas 入门中,有一段分析 Yahoo! Fiannce 的股票价格和成交量的代码,此代码年代已久,如果照写,根本不能正确运行,本篇文章总结了我遇到的几个问题,以及解决办法。
import pandas.io.data as web
all_data = {}
for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG']:
all_data[ticker] = web.get_data_yahoo(ticker, start, end)
price = DataFrame({tic: data['Adj Close']
for tic, data in all_data.iteritems()})
volumn = DataFrame({tic: data['Volume']
for tic, data in all_data.iteritems()})
接下来,解决以下问题:
对着书敲完代码,得到第一个错误:
意思就是 data 找不到啊,谷歌一下,原来是因为 data 模块从 pandas.io 迁移到了 pandas_datareader 下面了,所以不能 import 进来。
解决方法:把 pandas.io.data 替换为 pandas_datareader.data 即可。
执行步骤:
1、先安装 pandas_datareader
pip install pandas-datareader
2、把 pandas_datareader.data 模块 import 进来(我把别名从 web 换成了 pdr)
import pandas_datareader.data as pdr
(参考链接:https://www.jianshu.com/p/a02c4a058506 )
接着,发现第二个问题:
ImportError: cannot import name is_list_like
根据错误提示:
进去相应的 fred.py 文件查看,发现了:
from pandas.core.common import is_list_like
谷歌之,发现是 is_list_like 也搬家了,从 pandas.core.common 搬到 pandas.api.types 中去了。这里,基本有两种解决办法。第一种,是直接去修改 fred.py,第二种是在自己的代码里面声明一下导入 is_list_like 途径的改变。我采用了第二种方法:
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
(参考链接:https://stackoverflow.com/questions/50394873/import-pandas-datareader-gives-importerror-cannot-import-name-is-list-like )
至此,解决以上两个问题。
接着,爬取 Yahoo! Finance 股票数据的时候,出现第三个问题:
很明显,get_data_yahoo 这一 API 有问题。谷歌之,得到下面的解决办法。
首先,安装 fix_yahoo_finance:
pip install fix_yahoo_finance --upgrade --no-cache-dir
接着:
import fix_yahoo_finance as yf
yf.pdr_override()
只用把上面这段代码加进去,即可正常使用 get_data_yahoo。(参考链接:https://pypi.org/project/fix-yahoo-finance/ )
最后,在下载数据的时候,有一个小更新需要在代码中更正下,就是 Google 的 ticker 从 GOOG 变成了 GOOGL。(参考链接:https://stackoverflow.com/questions/23642194/loading-data-from-yahoo-finance-with-pandas )
这样一步步下来,文章开头书中的代码已经改善为下面可以正常运行的代码:
import datetime
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader.data as pdr
import fix_yahoo_finance as yf
yf.pdr_override()
from pandas import Series, DataFrame
start = datetime.datetime(2018, 1, 1)
end = datetime.date.today()
tickers = ['AAPL', 'IBM', 'MSFT', 'GOOGL']
all_data = {}
for ticker in tickers:
all_data[ticker] = pdr.get_data_yahoo(ticker, start, end)
price = DataFrame({tic: data['Adj Close']
for tic, data in all_data.iteritems()})
volumn = DataFrame({tic: data['Volume']
for tic, data in all_data.iteritems()})