Python 如何处理yfinance下载的多级列名

Python 如何处理yfinance下载的多级列名,python,python-3.x,pandas,dataframe,yfinance,Python,Python 3.x,Pandas,Dataframe,Yfinance,我有一个要一次下载的代码列表(tickerStrings)。当我尝试使用pandas的读取csv时,它不会像我从yfinance下载数据时那样读取csv文件 我通常通过以下方式访问我的数据:data['AAPL']或data['AAPL']。关闭,但当我从csv文件读取数据时,它不允许我这样做 if path.exists(data_file): data = pd.read_csv(data_file, low_memory=False) data = pd.DataFrame

我有一个要一次下载的代码列表(
tickerStrings
)。当我尝试使用pandas的读取csv时,它不会像我从yfinance下载数据时那样读取csv文件

我通常通过以下方式访问我的数据:
data['AAPL']
data['AAPL']。关闭
,但当我从csv文件读取数据时,它不允许我这样做

if path.exists(data_file):
    data = pd.read_csv(data_file, low_memory=False)
    data = pd.DataFrame(data)
    print(data.head())
else:
    data = yf.download(tickerStrings, group_by="Ticker", period=prd, interval=intv)
    data.to_csv(data_file)
以下是打印输出:

                  Unnamed: 0                 OLN               OLN.1               OLN.2               OLN.3  ...                 W.1                 W.2                 W.3                 W.4     W.5
0                        NaN                Open                High                 Low               Close  ...                High                 Low               Close           Adj Close  Volume
1                   Datetime                 NaN                 NaN                 NaN                 NaN  ...                 NaN                 NaN                 NaN                 NaN     NaN
2  2020-06-25 09:30:00-04:00    11.1899995803833  11.220000267028809  11.010000228881836  11.079999923706055  ...   201.2899932861328   197.3000030517578  197.36000061035156  197.36000061035156  112156
3  2020-06-25 09:45:00-04:00  11.130000114440918  11.260000228881836  11.100000381469727   11.15999984741211  ...  200.48570251464844  196.47999572753906  199.74000549316406  199.74000549316406   83943
4  2020-06-25 10:00:00-04:00  11.170000076293945  11.220000267028809  11.119999885559082  11.170000076293945  ...  200.49000549316406  198.19000244140625   200.4149932861328   200.4149932861328   88771
尝试访问数据时出现的错误:

Traceback (most recent call last):
File "getdata.py", line 49, in processData
    avg = data[x].Close.mean()
AttributeError: 'Series' object has no attribute 'Close'
将所有标记下载到具有单级列标题的单个数据帧中 选择1
  • 下载单个股票行情数据时,返回的dataframe列名为单个级别,但没有行情列
  • 这将下载每个ticker的数据,添加一个ticker列,并从所有所需的ticker创建一个数据帧
将yf财务导入为yf
作为pd进口熊猫
tickerStrings=['AAPL','MSFT']
df_list=list()
对于TickerString中的ticker:
数据=yf.下载(股票代码,分组依据=“股票代码”,句号=2d”)
data['ticker']=ticker#添加此列,因为dataframe不包含带有ticker的列
df_list.append(数据)
#将所有数据帧合并到单个数据帧中
df=pd.concat(df_列表)
#保存到csv
df.to_csv('ticker.csv'))
选择2
  • 下载所有标记并取消标记级别
    • group\u by='Ticker'
      将Ticker置于列名的
      级别=0
tickerStrings=['AAPL','MSFT']
df=yf.下载(tickerStrings,按class='Ticker',period='2d'分组)
df=df.stack(级别=0)。重命名_轴(['Date','Ticker'])。重置_索引(级别=1)

读取
yfinance
csv已使用多级列名存储
  • 如果希望保留并读入具有多级列索引的文件,请使用以下代码,这将使数据帧返回其原始形式
df=pd.read\u csv('test.csv',header=[0,1])
df.drop([0],axis=0,inplace=True)#删除此行,因为它只有一列带有日期
df[('Unnamed:0_level_0','Unnamed:0_level_1')]=pd.to_datetime(df[('Unnamed:0_level_0','Unnamed:0_level_1'),格式=“%Y-%m-%d”)#将第一列转换为日期时间
df.set_index('Unnamed:0_level_0','Unnamed:0_level_1'),inplace=True)#将第一列设置为索引
df.index.name=None#重命名索引
  • 问题是,
    tickerStrings
    是一个tickers列表,它会产生一个带有多级列名的最终数据帧
AAPL-MSFT
开-高-低-关调整关闭音量开-高-低-关调整关闭音量
日期
1980-12-12 0.513393 0.515625 0.513393 0.513393 0.405683 117258400南南
1980-12-15 0.488839 0.488839 0.486607 0.486607 0.384517 43971200南南
1980-12-16 0.453125 0.453125 0.4508930.4508930.356296 26432000南南
1980-12-17 0.462054 0.464286 0.462054 0.462054 0.365115 21610400南南
1980-12-18 0.475446 0.477679 0.475446 0.475446 0.375698 18362400南南
  • 当这被保存到csv时,它看起来像下面的示例,并导致一个数据帧,就像您遇到问题一样
,AAPL,AAPL,AAPL,AAPL,AAPL,AAPL,MSFT,MSFT,MSFT,MSFT,MSFT,MSFT,MSFT
,打开,高,低,关闭,调整关闭,音量,打开,高,低,关闭,调整关闭,音量
日期,,,,,,,,,,,,
1980-12-12,0.5133928656578064,0.515625,0.5133928656578064,0.5133928656578064,0.40568336844444275,117258400,,,,,,
1980-12-15,0.4888392984867096,0.4888392984867096,0.4866071343421936,0.4866071343421936,0.3845173120498657,43971200,,,,,,
1980-12-16,0.453125,0.453125,0.4508928656578064,0.4508928656578064,0.3562958240509033,26432000,,,,,,

将多个级别的列展平为单个级别,并添加一个标记列
  • 如果股票代码为列名的
    级别=0
    (顶部)
    • 使用
      group\u by='Ticker'
df.stack(级别=0)。重命名_轴(['Date','Ticker'])。重置_索引(级别=1)
  • 如果股票代码为列名的
    级别=1
    (底部)
df.stack(级别=1)。重命名_轴(['Date','Ticker'])。重置_索引(级别=1)

下载每个ticker并将其保存到单独的文件中
  • 我建议分别下载并保存每个股票代码,如下所示:
将yf财务导入为yf
作为pd进口熊猫
tickerStrings=['AAPL','MSFT']
对于TickerString中的ticker:
数据=yf.下载(股票代码,group_by=“ticker”,期间=prd,区间=intv)
data['ticker']=ticker#添加此列,因为dataframe不包含带有ticker的列
例如,data.to_csv(f'ticker{ticker}.csv')35;ticker_AAPL.csv
  • 数据
    看起来像
Open High Low Close Adj Close音量调节器
日期
1986-03-13 0.088542 0.101562 0.088542 0.097222 0.062205 1031788800毫英尺
1986-03-14 0.097222 0.102431 0.097222 0.100694 0.064427 308160000毫英尺
1986-03-17 0.100694 0.103299 0.100694 0.102431 0.065537 133171200毫英尺
1986-03-18 0.102431 0.103299 0.098958 0.099826 0.063871 67766400毫英尺
1986-03-19 0.099826 0.100694 0.097222 0.098090 0.062760 47894400毫英尺
  • 生成的csv将如下所示
日期、打开、高、低、关闭、调整关闭、音量、股票代码
1986-03-13,0.088541664183
df = yf.download(tickers, group_by="ticker")
d = {idx: gp.xs(idx, level=0, axis=1) for idx, gp in df.groupby(level=0, axis=1)}