我的Python心路历程 第十二期 (12.8 基金实战可视化之比较超过3只基金的趋势,日期不一样时做优化整合)

该文章介绍了如何使用Python进行基金趋势分析,特别是当基金的日期不一致时,通过pandas库进行数据整合,利用execjs处理JavaScript文件来获取基金数据,然后将数据合并并设置日期为索引,最后将处理后的数据保存为CSV文件,为基金的趋势可视化做好准备。
摘要由CSDN通过智能技术生成

背景

今天,尝试一下基于Python开发基金实战可视化之比较超过3只基金的趋势,遇到日期不一样,怎么优化整合?

分析

实质上就是在日期段没数据时补空值

开门见山看效果

运行效果图如下所示:
在这里插入图片描述

方案

上图以累计净值为例进行趋势类比。
重点需要关注的方面有:
1、通过execjs.compile方法读js文件内容。
2、解析js数据。
3、通过merge方法合并pandas数据结构对象,此处需要特别注意的是需要做一次赋值(merge方法return后的才是合并结果,不会改变self)。
4、日期的展示,需要设置为index并排序。
5、保存整合后的数据为csv文件。

核心代码如下:

# 比较超过3只基金的趋势,日期不一样时有做优化整合
def compare3mfsACWorth(fscodes, fstype):
    # 获取绝对路径,funddata为当前文件夹
    curpath = os.path.join(os.path.dirname(__file__), 'funddata')

    # 初始化汇总序列
    pdACWorthTrend = pd.DataFrame()
    # 定义字段名
    colSet = ['Date']
    # 定义title
    tname = fstype + ": "
    name = []
    code = []

    # 循环逐个执行fscodes
    for fs in fscodes:
        # 文件操作
        fileName = fs + 'content.js'
        file_object_path = os.path.join(curpath, fileName)
        f = open(file_object_path, 'r', encoding='utf-8')
        content = f.read()
        f.close()

        jsContent = execjs.compile(content)

        # 基金名称及代码
        name.append(jsContent.eval('fS_name'))
        code.append(jsContent.eval('fS_code'))

        # 累计净值走势=单位净值+累计分红
        ACWorthTrendData = jsContent.eval('Data_ACWorthTrend')
        ACWorthTrend = [v[1] for v in ACWorthTrendData]

        # x轴:日期。因为系统是毫秒级timeStamp故此需要除以1000取秒级timeStamp,否则转换后的日期不对
        # vtimeStamp = [int(v[0] / 1000) for v in ACWorthTrendData1]  # // 算法符号的结果可以直接取整
        # xs = pd.to_datetime(vtimeStamp, unit='s')  # , 看源码设定对应的unit,'s'类同format='%Y-%m-%dT%H:%M:%S'但其结果会出人意料的差
        # x轴:日期。获取年月日需要除以(1000 *24*3600),因为系统是毫秒级timeStamp。
        vtimeStamp = [int(v[0] / (1000 * 24 * 3600)) for v in ACWorthTrendData]  # // 算法符号的结果可以直接取整
        xs = pd.to_datetime(vtimeStamp, unit='D')  # , 看源码设定对应的unit,'s'类同format='%Y-%m-%dT%H:%M:%S'但其结果会出人意料的差

        # 提取x、y1、y2轴数据并整合, pd.merge适用于Series数据类型
        # 设置y轴数据
        sACWorthTrend = pd.Series(ACWorthTrend, name='ACWorth_' + fs)
        # 设置x轴数据
        stimeStamp = pd.Series(xs, name=colSet[0])
        pdACWorthTrendTmp = pd.merge(stimeStamp, sACWorthTrend, left_index=True, right_index=True)

        if pdACWorthTrend.empty:
            pdACWorthTrend = pdACWorthTrendTmp
            tname += fs
        else:
            # 合并数据
            pdACWorthTrend = pdACWorthTrend.merge(pdACWorthTrendTmp, how='outer', on=colSet[0])#, suffixes=('_' + code))
            tname += ' vs ' + fs

    tname += " " + u"趋势类比"

    # 设置索引为Date列
    pdACWorthTrend.set_index(colSet[0], inplace=True)

    # 以日期排序,但是存在csv文件的依然有部分没有顺序存储
    pdACWorthTrend.sort_index()

    # 存数据fstype
    fileName = fstype + '.csv'
    file_object_path = os.path.join(curpath, fileName)
    pdACWorthTrend.to_csv(file_object_path)

    # 当for循环有两个需要迭代的对象时,要用zip对这多个变量封装,否则会报错“too many values to unpack”
    cols = []
    for n, c in zip(name, code):
        cols.append(n + '_' + c)
    # 设置新列
    pdACWorthTrend.columns = cols

    # 趋势图类比
    # 主次轴差异化显示
    # tech_df.plot(secondary_y=colSet[2], grid=True)
    # 主轴显示
    pdACWorthTrend.plot()
    ax = plt.gca()  # 表明设置图片的各个轴,plt.gcf()表示图片本身
    ax.xaxis.set_major_formatter(mdate.DateFormatter(
        '%Y-%m-%d'))  # 横坐标标签显示的日期格式;注意,如果不加语句plt.gca().xaxis.set_major_formatter(mdate.DateFormatter('%Y-%m-%d')),则横坐标只显示年份
    plt.xlabel(u'日期')
    plt.ylabel(u'累计净值')
    plt.title(tname)
    # plt.text('2017-01-01', 0.65, showStr)

    plt.gcf().autofmt_xdate()  # 自动旋转日期标记
    # plt.tight_layout()

    # 测试代码开始————————————————————————————————————————————————————————————————————————————————
    # 测试代码结束————————————————————————————————————————————————————————————————————————————————

    plt.show()
    return

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值