1. 引言
下载数据的时候,通常获得的数据是以面板形式排列的,如图1所示,但也会遇到某些以时序形式排列的数据,如图2所示。显然面板形式的数据更便于使用,但有时会出现所需数据只有时序形式的情况,如使用wind数据库的证券分析工具时,就只能下载时序形式的数据。因此,本文提供了一种(不太聪明的)将时序形式转化为面板形式数据的思路。欢迎大家一起讨论优化本代码。
图1 面板形式的数据
图2 时序形式的数据
2. 这个不聪明的方法
本文以从wind股票数据分析工具中获取的销售费用/营业总收入数据为例介绍本方法。
2.1 导出wind数据库中的数据到excel中
形式如图3所示。检查A1格子是否严格为“证券代码”四字,若有多余的箭头或符号,请务必删除!如有出入程序会报错【不聪明1】。除此之外,不要对表格进行任何更改并保存到指定位置(需记住该位置)。
图3 从wind中导出数据
2.2 Python编辑器打开本代码,输入2.1保存的文件的路径
此处推荐使用绝对路径,修改图4中绿色path的部分。
图4 修改路径
2.3 运行代码
该代码运行后会在与导入文件相同位置生成一个文件夹,如图5所示。文件夹内是依据证券代码切割开的分表,即文件夹内每一个表都只收录了与文件名相同的证券指标的面板格式数据,如图6所示。
虽然Python中有将多个excel表合并的代码,但是若拼接的表过多则会超过python内存,如拼接股票市场约5000个表格时。因此,本方法接下来需使用excel内置功能完成最后的整体拼接【不聪明2】。
图5 文件夹
图6 分表内容
2.4 面板格式数据总表制作
新建总表excel,数据=>获取数据=>来自文件=>从文件夹=>选择创建文件加的位置=>合并并转换数据=>关闭并上载,如图7、8、9所示。
最终得到如图1所示的面板格式数据。
图7 从与原始文件同一位置的文件夹导入数据
图8 合并并转换数据
图9 关闭并上载
3. 不足与展望
本代码除了文中提到的2处不聪明之处外,实际运行中还存在以下问题:【不聪明3】只能适用于大部分wind数据,从其他数据库中调出的数据有于格式微小差异,使用中易报错。【不聪明4】部分wind报表由于格式特殊(如报表附注内容),也会出现错误。
欢迎大家一起讨论该代码的优化方法,使其成为一个聪明的方法。>v<
4. 代码
import pandas as pd
import os
import numpy as np
pathes = os.path.abspath(r'path') # 待处理文件的位置,替换掉单词path,
wjj = str(os.path.basename(pathes).split('.')[0])#在与原始文件相同的目录下创建一个文件夹用于储存切好的excel
if os.path.exists(os.path.join(os.path.dirname(pathes), wjj)) == 0:
os.mkdir(os.path.join(os.path.dirname(pathes), wjj)) # 制作收集切割后文件的文件夹,以原始文件名命名
box = os.path.abspath(os.path.join(os.path.dirname(pathes), wjj))
proto = pd.read_excel(pathes, sheet_name=0).T.reset_index()#转置并初步处理格式,处理后会变成代码在行、日期在列的形式,如果原始文件就是这种格式,请手动删除T.
code0=proto.iloc[0]#该部分的处理是调整表头格式、删除多余行,请依据需要修改参数
proto = pd.DataFrame(proto).drop(axis=0, index=1).reset_index(drop=True)
proto.rename(columns=code0,inplace=True)
proto.rename(columns={'证券代码':'日期'},inplace=True)
proto=proto.drop(axis=0, index=0).reset_index(drop=True)
ENTRY=proto['日期'].str.slice(0,-18)[0]#该部分操作为调整日期格式,请依据原始文件需要修改参数
proto['日期']=proto['日期'].str.slice(-12,-6)#从后向前计算索引时,前后的索引填写顺序仍是从左向右填写,此时需要注意python取值范围默认左闭右开
for DATE in proto['日期']:#将不规律的日期处理成标准日期格式
if DATE[-2:]=='中报':
newDATE = DATE[0:4]+'/6/30'
else:
newDATE = DATE[0:4] + '/12/31'
proto['日期']=proto['日期'].replace(DATE,newDATE)
colname=list(proto.columns)[1:]
#该循环会将原本的表格依列进行切分,拼接成依次为日期、证券代码、条目的形式,并保存在之前创建的文件夹中,文件以证券代码依次命名
for cols in colname:
if '证券代码' in proto:
proto['证券代码'] = proto.loc[proto['证券代码'] == all(proto['证券代码'])] = cols
else:
proto.insert(column='证券代码', loc=2, value=cols)
proto.rename(columns={cols:ENTRY},inplace=True)
out_merged = pd.concat([proto['日期'],proto['证券代码'],proto[ENTRY]],axis=1,)
out_merged.to_excel(os.path.join(os.path.dirname(pathes),wjj,cols[0:6]+'.xlsx'),index=False)#请注意,文件名中不能有英文的“:”、“.”等字符,如存在请自行替换
proto.rename(columns={ENTRY: cols}, inplace=True)
print(cols)