You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从现有DataFrame创建多级索引列并按Symbol拆分数据?

按Symbol拆分电子表格格式数据的解决方案

问题背景

给定如下电子表格格式的原始数据:

import pandas as pd, numpy as np
data1 = [['symbol',    'appl',  'goog',  None,     'msft',  None,   None,    None],
         ['date'  ,    'close', 'close', 'volume', 'close', 'open', 'high', 'low'],
         ['1999-01-10', 100,     101,    10000,     102,    102,    104,     105],
         ['1999-01-11', 200,     201,    10000,     202,    202,    204,     205]]

df = pd.DataFrame(data1)

需要按symbol拆分数据:

  • appl对应仅含[date, close]列的DataFrame
  • goog对应含[date, close, volume]列的DataFrame
  • msft对应含[close, open, high, low]列的DataFrame

尝试通过多级索引分组切片实现,但代码执行失败,已尝试的部分代码如下:

df = pd.DataFrame(data1)
df = df.ffill(axis=1)
#add first column by using first row
df.columns = df[:1].values.tolist()
df = df[1:]
df.columns = [df.columns, df[:1].values.tolist()]
#repeat for the fields row (2nd column above, now first column after above line)
#df.columns = pd.MultiIndex.from_product(df.columns.levels + df[:1].values.tolist())
#df.set_axis(pd.MultiIndex.from_product([df.columns, df[:1].values.tolist()]), axis=1)

可行解决方案

实现思路

先把前两行转成多级列索引,解决symbol和字段的对应问题,再把数据行转成标准DataFrame,最后按symbol提取对应字段即可。

完整代码

import pandas as pd
import numpy as np

data1 = [['symbol',    'appl',  'goog',  None,     'msft',  None,   None,    None],
         ['date'  ,    'close', 'close', 'volume', 'close', 'open', 'high', 'low'],
         ['1999-01-10', 100,     101,    10000,     102,    102,    104,     105],
         ['1999-01-11', 200,     201,    10000,     202,    202,    204,     205]]

# 第一步:处理表头,生成多级列索引
header_rows = pd.DataFrame(data1[:2])
# 填充第一行的空值,让每个字段都对应到正确的symbol
header_rows.iloc[0] = header_rows.iloc[0].ffill()
# 用前两行创建多级索引(第一层是symbol,第二层是字段名)
multi_columns = pd.MultiIndex.from_arrays(header_rows.values)

# 第二步:处理数据行,生成标准DataFrame
df = pd.DataFrame(data1[2:], columns=multi_columns)
# 把数值列转成数值类型(date列保持字符串)
df = df.apply(pd.to_numeric, errors='ignore')
# 将date列设为索引,方便后续筛选
df = df.set_index(('date', 'date'))
df.index.name = 'date'

# 第三步:按symbol拆分数据
# 获取所有要拆分的symbol(排除第一列的'symbol')
target_symbols = header_rows.iloc[0].unique()[1:]

# 用字典存储每个symbol对应的DataFrame
symbol_dataframes = {}
for sym in target_symbols:
    # 提取当前symbol对应的所有列
    cols_for_sym = [col for col in df.columns if col[0] == sym]
    # 生成对应DataFrame并简化列名(去掉symbol层级)
    symbol_dataframes[sym] = df[cols_for_sym].copy()
    symbol_dataframes[sym].columns = symbol_dataframes[sym].columns.get_level_values(1)

# 打印结果验证
print("appl 对应的数据:")
print(symbol_dataframes['appl'])
print("\ngoog 对应的数据:")
print(symbol_dataframes['goog'])
print("\nmsft 对应的数据:")
print(symbol_dataframes['msft'])

运行结果

执行后会得到三个独立的DataFrame:

  • symbol_dataframes['appl'] 包含date(作为索引)和close列
  • symbol_dataframes['goog'] 包含date(作为索引)、close和volume列
  • symbol_dataframes['msft'] 包含date(作为索引)、close、open、high、low列

如果需要将date作为普通列而非索引,只需要去掉df = df.set_index(('date', 'date'))和df.index.name = 'date'这两行即可。

内容的提问来源于stack exchange,提问作者mike01010

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:20:41