如何从现有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]列的DataFramegoog对应含[date, close, volume]列的DataFramemsft对应含[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
相关产品推荐
相关产品推荐

