首页 > 解决方案 > 如何将数据框展平为 1 行并更改列以使列为:“column1.index1”、“column1.index2”等?

问题描述

我正在尝试使用 For 循环和 pd.read_html 函数来抓取表格。

每个 html 有 17 个表。

我首先从一个 Excel 文件中提取代码并将它们变成一个列表。然后我运行它们:

import pandas as pd

df = pd.read_excel('C:/Users/Jacob/Downloads/CEF Tickers.xlsx', sheet_name='Sheet1')

tickers_list = df['Ticker'].tolist()

# There are some test tickers: ["ASA", "FAX", "IAF"]

df_list1 = []

for ticker in tickers_list:
    df_list1.append(pd.read_html(f'https://www.cefconnect.com/fund/{ticker}', header=0)[0])

在这里,我从每个 pd.html 表格抓取中获取第一个数据帧。实际上有 17 个表被拉出。我的计划是:

df_list1 = []
df_list2 = []
...
df_list17 = []

for ticker in tickers_list:
    df_list1.append(pd.read_html(f'https://www.cefconnect.com/fund/{ticker}', header=0)[0])
    df_list2.append(pd.read_html(f'https://www.cefconnect.com/fund/{ticker}', header=0)[1])
    ...
    df_list17.append(pd.read_html(f'https://www.cefconnect.com/fund/{ticker}', header=0)[16])

df_list1 中的数据框如下所示

我一直在寻找方法来尝试将 df_list1 中的数据帧转换为此但无济于事。

当 df_list1 中的数据框看起来像这样时,我可以使用 pd.concat 并获取列表并将其变成一个庞大的数据框。然后将所有 df_list1 到 df_list17 连接在一起,以代码为索引。

我之前使用过 pd.json_normalize 函数来展平这样的数据集。我需要将每个数据框变成字典并做同样的事情吗?

谢谢大家的时间。

标签: pythonpandasdataframe

解决方案


试试这个,使用字典而不是列表,这样我可以在连接的数据框中跟踪我的代码,然后重塑(展平):

tickers_list = ["ASA", "FAX", "IAF"]

df_list1 = {}

for ticker in tickers_list:
    df_list1[ticker]= pd.read_html(f'https://www.cefconnect.com/fund/{ticker}', header=0)[0]
    

df_out = pd.concat(df_list1, keys=df_list1.keys())
df_out = df_out.rename(columns={'Unnamed: 0': 'Prices'})
df_out = df_out.set_index('Prices', append=1).reset_index(level=1, drop=True).unstack()

df_out.columns = df_out.columns.map('_'.join)
df_out

输出:

  SharePrice_52 Wk Avg SharePrice_52 Wk High SharePrice_52 Wk Low SharePrice_Current NAV_52 Wk Avg NAV_52 Wk High NAV_52 Wk Low NAV_Current Premium/Discount_52 Wk Avg Premium/Discount_52 Wk High Premium/Discount_52 Wk Low Premium/Discount_Current
ASA               $15.32                $25.45                $8.16             $20.80        $18.08         $27.91        $10.55      $24.55                    -15.52%                      -8.05%                    -19.86%                  -15.27%
FAX                $3.99                 $4.49                $2.60              $3.87         $4.65          $4.90         $3.98       $4.62                    -14.29%                      -9.09%                    -30.05%                  -16.23%
IAF                $4.78                 $5.62                $2.99              $4.50         $5.31          $6.11         $3.45       $5.21                    -10.20%                      -4.38%                    -14.10%                  -13.63%

tickers_list = ["ASA", "FAX", "IAF"]

df_list1 = {}

for ticker in tickers_list:
    df_list1[ticker]= pd.read_html(f'https://www.cefconnect.com/fund/{ticker}', header=0)[1]
    

df_out = pd.concat(df_list1, keys=df_list1.keys())
#df_out = df_out.rename(columns={'Unnamed: 0': 'Prices'})
df_out = df_out.unstack()

df_out.columns = [f'{i}_{j}' for i, j in df_out.columns]
df_out

推荐阅读