如何在Python中将指定结构的DataFrame转换为面板数据格式?
用Pandas将数据转换为目标面板格式
嘿,我来帮你搞定这个问题!咱们用Python的Pandas库就能轻松把这两份数据转成你想要的面板格式,步骤很清晰,我给你一步步拆解:
第一步:明确数据结构,准备基础数据
首先给两份数据起个好记的名字:把包含代码详情(comp、name、base这些)的表叫info_df,日期和代码对应的表叫date_code_df。我把你的示例数据写成Pandas可直接运行的格式,方便你测试:
import pandas as pd # 代码详情表 info_df = pd.DataFrame({ 'comp': ['A122630', 'A123320', 'A123320', 'A122630', 'A292340'], 'name': ['삼성자산운용', '미래에셋자산운용', '한국투자신탁운용', '키움투자자산운용', '한국투자신탁운용'], 'base': ['KODEX 레버리지 코스피 200', 'TIGER 레버리지 코스피 200', 'KINDEX 레버리지 코스피 200', 'KOSEF 레버리지 국고채 지수', 'KINDEX 일본TOPI TOPIX'], 'lstdt': ['2010/02/22', '2010/04/09', '2012/01/27', '2012/10/30', '2014/06/16'] }) # 日期-代码对应表 date_code_df = pd.DataFrame({ 'date': ['20180102', '20180102', '20180409', '20180409', '20180409'], 'code': ['A122630', 'A123320', 'A123320', 'A122630', 'A292340'] })
第二步:合并两份数据
咱们需要把日期表和详情表通过代码字段关联起来——也就是date_code_df里的code和info_df里的comp,用merge方法就能搞定:
# 左连接保证日期表的所有记录都被保留 merged_df = date_code_df.merge(info_df, left_on='code', right_on='comp', how='left')
这一步之后,你会得到一个包含日期、代码、对应公司名称、产品基准、上市日期的完整表,每条记录对应一个「日期+代码」的组合。
第三步:重塑为宽格式面板数据
现在要把这个长表转成你想要的「日期一行,每个代码的信息作为列」的面板格式,用pivot方法就能实现:
# 以date为行索引,code为列维度,展开name/base/lstdt字段 panel_df = merged_df.pivot(index='date', columns='code', values=['name', 'base', 'lstdt']) # 调整列名,让结构更直观:比如把('name', 'A122630')改成'A122630_name' panel_df.columns = [f'{col[1]}_{col[0]}' for col in panel_df.columns] # 把date从索引变回普通列,符合常规面板数据格式 panel_df = panel_df.reset_index()
运行完之后,你得到的panel_df会是这样的结构:
| date | A122630_name | A122630_base | A122630_lstdt | A123320_name | A123320_base | A123320_lstdt | A292340_name | A292340_base | A292340_lstdt |
|---|---|---|---|---|---|---|---|---|---|
| 20180102 | 삼성자산운용 | KODEX 레버리지 코스피 200 | 2010/02/22 | 미래에셋자산운용 | TIGER 레버리지 코스피 200 | 2010/04/09 | NaN | NaN | NaN |
| 20180409 | 삼성자산운용 | KODEX 레버리지 코스피 200 | 2010/02/22 | 미래에셋자산운용 | TIGER 레버리지 코스피 200 | 2010/04/09 | 한국투자신탁운용 | KINDEX 일본TOPI TOPIX | 2014/06/16 |
必看:处理重复代码的特殊情况
注意到你的info_df里存在同一个代码对应多条记录的情况吗?比如A123320对应了两个不同的公司。这种情况下直接用pivot会报错,所以得先清理数据:
方案1:保留最新的记录
按上市日期排序,保留每个代码最新的那条记录:
# 按comp分组,保留lstdt最晚的记录 info_df_clean = info_df.sort_values('lstdt', ascending=False).drop_duplicates('comp', keep='first')
方案2:合并多条记录
如果不想丢失数据,把同一个代码的所有信息用逗号合并:
# 按comp分组,合并name、base、lstdt字段 info_df_clean = info_df.groupby('comp').agg({ 'name': lambda x: ', '.join(x), 'base': lambda x: ', '.join(x), 'lstdt': lambda x: ', '.join(x) }).reset_index()
清理完数据后,再重复前面的合并和重塑步骤就没问题啦!
内容的提问来源于stack exchange,提问作者Hannah Lee
相关产品推荐
相关产品推荐

