使用 transform 进行数据转换第一部分

更多关于Apache ECharts的文档,请阅读:

《Apache ECharts教程》


Apache EChartsTM 5 开始支持了“数据转换”( data transform )功能。在 echarts 中,“数据转换” 这个词指的是,给定一个已有的“数据集”(dataset)和一个“转换方法”(transform),echarts 能生成一个新的“数据集”,然后可以使用这个新的“数据集”绘制图表。这些工作都可以声明式地完成。

抽象地来说,数据转换是这样一种公式:outData = f(inputData)。f 是转换方法,例如:filter、sort、regression、boxplot、cluster、aggregate(todo) 等等。有了数据转换能力后,我们就至少可以做到这些事情:

  • 把数据分成多份用不同的饼图展现。
  • 进行一些数据统计运算,并展示结果。
  • 用某些数据可视化算法处理数据,并展示结果。
  • 数据排序。
  • 去除或直选择数据项。

数据转换基础使用

在 echarts 中,数据转换是依托于数据集(dataset)来实现的. 我们可以设置 dataset.transform 来表示,此 dataset 的数据,来自于此 transform 的结果。例如。

var option = {
    dataset: [{
        // 这个 dataset 的 index 是 `0`。
        source: [
            ['Product', 'Sales', 'Price', 'Year'],
            ['Cake', 123, 32, 2011],
            ['Cereal', 231, 14, 2011],
            ['Tofu', 235, 5, 2011],
            ['Dumpling', 341, 25, 2011],
            ['Biscuit', 122, 29, 2011],
            ['Cake', 143, 30, 2012],
            ['Cereal', 201, 19, 2012],
            ['Tofu', 255, 7, 2012],
            ['Dumpling', 241, 27, 2012],
            ['Biscuit', 102, 34, 2012],
            ['Cake', 153, 28, 2013],
            ['Cereal', 181, 21, 2013],
            ['Tofu', 395, 4, 2013],
            ['Dumpling', 281, 31, 2013],
            ['Biscuit', 92, 39, 2013],
            ['Cake', 223, 29, 2014],
            ['Cereal', 211, 17, 2014],
            ['Tofu', 345, 3, 2014],
            ['Dumpling', 211, 35, 2014],
            ['Biscuit', 72, 24, 2014],
        ],
        // id: 'a'
    }, {
        // 这个 dataset 的 index 是 `1`。
        // 这个 `transform` 配置,表示,此 dataset 的数据,来自于此 transform 的结果。
        transform: {
            type: 'filter',
            config: { dimension: 'Year', value: 2011 }
        },
        // 我们还可以设置这些可选的属性: `fromDatasetIndex` 或 `fromDatasetId`。
        // 这些属性,指定了,transform 的输入,来自于哪个 dataset。例如,
        // `fromDatasetIndex: 0` 表示输入来自于 index 为 `0` 的 dataset 。又例如,
        // `fromDatasetId: 'a'` 表示输入来自于 `id: 'a'` 的 dataset。
        // 当这些属性都不指定时,默认认为,输入来自于 index 为 `0` 的 dataset 。
    }, {
        // 这个 dataset 的 index 是 `2`。
        // 同样,这里因为 `fromDatasetIndex` 和 `fromDatasetId` 都没有被指定,
        // 那么输入默认来自于 index 为 `0` 的 dataset 。
        transform: {
            // 这个类型为 "filter" 的 transform 能够遍历并筛选出满足条件的数据项。
            type: 'filter',
            // 每个 transform 如果需要有配置参数的话,都须配置在 `config` 里。
            // 在这个 "filter" transform 中,`config` 用于指定筛选条件。
            // 下面这个筛选条件是:选出维度( dimension )'Year' 中值为 2012 的所有
            // 数据项。
            config: { dimension: 'Year', value: 2012 }
        }
    }, {
        // 这个 dataset 的 index 是 `3`。
        transform: {
            type: 'filter',
            config: { dimension: 'Year', value: 2013 }
        }
    }],
    series: [{
        type: 'pie', radius: 50, center: ['25%', '50%'],
        // 这个饼图系列,引用了 index 为 `1` 的 dataset 。也就是,引用了上述
        // 2011 年那个 "filter" transform 的结果。
        datasetIndex: 1
    }, {
        type: 'pie', radius: 50, center: ['50%', '50%'],
        datasetIndex: 2
    }, {
        type: 'pie', radius: 50, center: ['75%', '50%'],
        datasetIndex: 3
    }]
};

下面是上述例子的效果,三个饼图分别显示了 2011、2012、2013 年的数据。
在这里插入图片描述

现在我们简单总结下,使用 transform 时的几个要点:

  • 在一个空的 dataset 中声明 transform, fromDatasetIndex/fromDatasetId 来表示我们要生成新的数据。
  • 系列引用这个 dataset 。

数据转换的进阶使用

链式声明 transform

transform 可以被链式声明,这是一个语法糖。

option: {
    dataset: [{
        source: [ ... ] // 原始数据
    }, {
        // 几个 transform 被声明成 array ,他们构成了一个链,
        // 前一个 transform 的输出是后一个 transform 的输入。
        transform: [{
            type: 'filter',
            config: { dimension: 'Product', value: 'Tofu' }
        }, {
            type: 'sort',
            config: { dimension: 'Year', order: 'desc' }
        }]
    }],
    series: {
        type: 'pie',
        // 这个系列引用上述 transform 的结果。
        datasetIndex: 1
    }
}

注意:理论上,任何 transform 都可能有多个输入或多个输出。但是,如果一个 transform 被链式声明,它只能获取前一个 transform 的第一个输出作为输入(第一个 transform 除外),以及它只能把自己的第一个输出给到后一个 transform (最后一个 transform 除外)。

一个 transform 输出多个 data

在大多数场景下,transform 只需输出一个 data 。但是也有一些场景,需要输出多个 data ,每个 data 可以被不同的 series 或者 dataset 所使用。

例如,在内置的 “boxplot” transform 中,除了 boxplot 系列所需要的 data 外,离群点( outlier )也会被生成,并且可以用例如散点图系列显示出来。例如,example。

我们提供配置 dataset.fromTransformResult 来满足这种情况,例如:

option = {
    dataset: [{
        // 这个 dataset 的 index 为 `0`。
        source: [...] // 原始数据
    }, {
        // 这个 dataset 的 index 为 `1`。
        transform: {
            type: 'boxplot'
        }
        // 这个 "boxplot" transform 生成了两个数据:
        // result[0]: boxplot series 所需的数据。
        // result[1]: 离群点数据。
        // 当其他 series 或者 dataset 引用这个 dataset 时,他们默认只能得到
        // result[0] 。
        // 如果想要他们得到 result[1] ,需要额外声明如下这样一个 dataset :
    }, {
        // 这个 dataset 的 index 为 `2`。
        // 这个额外的 dataset 指定了数据来源于 index 为 `1` 的 dataset。
        fromDatasetIndex: 1,
        // 并且指定了获取 transform result[1] 。
        fromTransformResult: 1
    }],
    xAxis: {
        type: 'category'
    },
    yAxis: {
    },
    series: [{
        name: 'boxplot',
        type: 'boxplot',
        // Reference the data from result[0].
        // 这个 series 引用 index 为 `1` 的 dataset 。
        datasetIndex: 1
    }, {
        name: 'outlier',
        type: 'scatter',
        // 这个 series 引用 index 为 `2` 的 dataset 。
        // 从而也就得到了上述的 transform result[1] (即离群点数据)
        datasetIndex: 2
    }]
};

另外,dataset.fromTransformResult 和 dataset.transform 能同时出现在一个 dataset 中,这表示,这个 transform 的输入,是上游的结果中以 fromTransformResult 获取的结果。例如:

{
    fromDatasetIndex: 1,
    fromTransformResult: 1,
    transform: {
        type: 'sort',
        config: { dimension: 2, order: 'desc' }
    }
}

在开发环境中 debug

使用 transform 时,有时候我们会配不对,显示不出来结果,并且不知道哪里错了。所以,这里提供了一个配置项 transform.print 方便 debug 。这个配置项只在开发环境中生效。如下例:

option = {
    dataset: [{
        source: [ ... ]
    }, {
        transform: {
            type: 'filter',
            config: { ... }
            // 配置为 `true` 后, transform 的结果
            // 会被 console.log 打印出来。
            print: true
        }
    }],
    ...
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Visual C++程序开发范例宝典配套光盘,因大小受限,所以分成8部分上传,必须全部下载才能正常解压! 第1章 窗体与界面设计 1.1 菜单应用实例 实例001 在系统菜单中添加菜单项 实例002 带图标的程序菜单 实例003 根据表中数据动态生成菜单 实例004 浮动的菜单 1.2 弹出菜单应用实例 实例005 在控件上单击右键弹出菜单 实例006 个性化的弹出菜单 实例007 任务栏托盘弹出菜单 1.3 工具栏应用实例 实例008 带背景的工具栏 实例009 带图标的工具栏 实例010 带下拉菜单的工具栏 实例011 可调整按钮位置的工具栏 实例012 浮动工具栏 实例013 根据表中数据动态生成工具栏 实例014 具有提示功能的工具栏 1.4 状态栏应用实例 实例015 带进度条的状态栏 实例016 动画效果的状态栏 实例017 滚动字幕的状态栏 1.5 导航界面应用实例 实例018 Outlook导航界面 实例019 树状导航界面 实例020 按钮导航界面 实例021 类QQ导航菜单 1.6 界面窗体应用实例 实例022 背景为渐变色的程序界面 实例023 椭圆形的程序界面 实例024 自绘窗体界面 实例025 类似Windows XP的程序界面 实例026 窗体融合技术 实例027 限制对话框最大时的窗口大小 1.7 多媒体宣传光盘应用实例 实例028 多媒体宣传光盘主界面 实例029 自动运行的多媒体宣传光盘 1.8 多媒体触摸屏程序应用实例 实例030 采购中心多媒体触摸屏程序 实例031 为触摸屏程序添加虚拟键盘 1.9 窗体位置应用实例 实例032 不可移动的窗体 实例033 始终在最上面的窗体 实例034 动画显示窗体 实例035 以时钟显示界面窗体 1.10 窗体标题栏应用实例 实例036 闪烁的窗体标题栏 实例037 拖动没有标题栏的窗体 实例038 禁用标题栏上的最大化、最小化或关闭按钮 1.11 窗体形状及应用 实例039 半透明窗体 实例040 创建字型窗体 实例041 百叶窗窗体 实例042 类似Office助手 第2章 控件应用 2.1 按钮控件典型实例 实例043 AVI动画按钮 实例044 GIF动画按钮 实例045 图文按钮 实例046 不规则按钮 2.2 EditBox控件典型实例 实例047 为EditBox设置新的系统菜单 实例048 为EditBox控件添加列表选择框 实例049 多彩边框的编辑框 实例050 改变编辑框文本颜色 2.3 ListBox控件典型实例 实例051 利用ListBox控件实现标签式数据选择 实例052 在ListBox控件间实现数据交换 实例053 列表项的提示条 2.4 ComboBox控件典型实例 实例054 将数据表中的字段添加到ComboBox控件 实例055 带查询功能的ComboBox控件 实例056 自动调整组合框的宽度 实例057 颜色组合框 实例058 多列显示的组合框 2.5 ListControl控件典型实例 实例059 将数据库中的数据表添加到ListControl控件 实例060 利用ListControl控件浏览数据 实例061 利用ListControl控件制作导航界面 实例062 在列表视图中拖动视图项 实例063 利用列标题对列表视图进行数据排序 实例064 具有文本录入功能的ListControl控件 2.6 TreeControl控件典型实例 实例065 多级数据库树状结构数据显示 实例066 可动态修改节点的树状结构 实例067 带复选功能的树状结构 实例068 显示磁盘目录 实例069 树型提示框 2.7 RichEdit控件典型实例 实例070 利用RichEdit显示Word文档 实例071 利用RichEdit控件实现文字定位与标识 实例072 利用RichEdit控件显示图文数据 2.8 图形类控件典型实例 实例073 图文数据录入 实例074 带有滚动条的图形控件 2.9 滚动条控件典型实例 实例075 自定义滚动条控件 2.10 控件数组典型实例 实例076 向窗体中动态添加控件 实例077 公交线路模拟 第3章 图形技术 3.1 绘制图形 实例078 绘制正弦曲线 实例079 绘制艺术图案 实例080 画图程序 实例081 绘制立体模型 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的图像浏览器 3.3 图片效果 实例089 图片马赛克效果 实例090 图片百叶窗效果 实例091 电影胶片特效 实例092 翻
数据整理 ⼤数据整理——数据集成 数据集成 数据集成 数据集成 1.背景: 背景: 因业务需要,事业单位内部普遍构建了多个异构的信息系统,这些信息系统中管理的数据源彼此独⽴、相互封闭,形成"信息孤岛"⽆法形成 快速有效的共享。 2.定义: 定义: 数据集成把⼀组⾃治、异构数据源中的数据进⾏逻辑或物理上的集中,并对外提供统⼀的访问接⼝,从⽽实现全⾯的数据共享。 3.举例: 举例: 杭州市政府⼯作报告中的"最多跑⼀次"改⾰,许多互联⽹应⽤(包括机票、酒店,餐饮,租房,商品⽐价等服务)都是把来⾃不同数据源的 数据进⾏有效集成,对外提供统⼀的访问服务。 4.解决⽅案 解决⽅案 数据源的异构性和⾃治性是数据集成系统⾯临的两个主要挑战。针对这两个挑战,数据集成通常采⽤如下两种解决⽅案。 4.1数据仓库 数据仓库 ⼈们把⼀组⾃治数据源中的数据加载并存储到⼀个物理数据库(称为数据仓库)中,然后在数据仓库上对集成后的数据进⾏后续的操作和分 析。如下图所⽰,基于数据仓库的数据集成系统架构 基于数据仓库的数据集成系统架构 数据仓库技术涉及的技术包括ETL、元数据管理和数据仓库本⾝涉及的技术。 ETL:定期地从各个数据源中抽取(extract)、转换transform)、加载(load)数据数据仓库中. 数据仓库:物理数据库,存放从数据源ETL的数据,以供数据应⽤层使⽤。 元数据管理:涉及对数据源的描述、对数据仓库中数据的描述、数据仓库中数据数据源中数据之间的语义映射。 4.2虚拟集成系统 虚拟集成系统 在虚拟集成系统中,数据保存在原来的数据源中,只在查询时才需要访问。如下图所⽰,基于中间模式的数据集成系统架构。 基于中间模式的数据集成系统架构 虚拟集成系统主要使⽤中间模式建⽴全局数据的逻辑视图,为异构数据源提供⾼层次的数据访问服务。 数据库:提供数据,独⽴性强 封装器: 负责把上层⽤户的查询转发到数据源,并把数据源返回的结果转发给上层的应⽤ 中间模式:向下协调各数据源系统,向上为访问集成数据的应⽤提供统⼀数据模式和数据访问的通⽤接⼝。 元数据:维护数据源的基本信息以及中间模式到数据源之间的语义映射等。 4.3 技术细节 技术细节 ⽆论是基于数据仓库还是基于中间模式的数据集成系统,都需要完成实体与关联抽取、模式匹配(schema matching)、实体对齐(record linkage或entity resolution)和实体融合(data fusion)这4个步骤。 4.3.1 实体与关联抽取 实体与关联抽取 ⾯向结构化数据的实体与关联抽取技术⽐较直观,⾯向⾮结构化数据的实体与关联抽取****可参考第4.1节。** 4.3.2 模式匹配 模式匹配 模式匹配主要⽤于发现并映射两个或多个异构数据源之间的属性对应关系,在⼤规模数据背景下尤为重要。⽬前,基于朴素贝叶斯、 stacking等机器学习算法的模式匹配得到了⼴泛的研究,并在某些特定领域得到了良好的应⽤。基于模式匹配,实体对齐的⽬标是根据匹配 属性的记录特征,将数据源中指代同⼀实体的记录连接起来。 4.3.3 实体对齐 实体对齐 实体对齐主要分为3个步骤:获取候选集、成对匹配、聚簇处理。⼴义地说,实体对齐的⽅法可以划分为⽆监督学习和有监督学习。随着⼈ ⼯智能技术的发展,基于决策树、Logistic回归、⽀持向量机(sup port vector machine,SVM)的机器学习⽅法以及基于词向量(word embedding)的深度学习⽅法被应⽤于实体对齐,以提⾼算法的性能。 4.4.4 实体融合 实体融合 实体对齐可以把⼀组数据源中同⼀实体的不同记录连接起来,由于数据质量问题,这些记录在描述同⼀实体时可能存在数据冲突,例如同⼀ 个⼈的住址在不同数据源之间的描述可能是不⼀样的。 因此,在数据集成的最终环节中,实体融合旨在消除不同数据源之间同⼀个实体属性值的冲突,将不同的数据信息进⾏综合,从⽽提取出统 ⼀、丰富、⾼精度的数据。实体融合的主要⽅法包括基于规则的⽆监督学习、结合标注数据的半监督学习等。虽然基于标注数据的半监督学 习在精度、召回率等⽅⾯均获得了令⼈满意的效果,但是其最⼤的挑战在于带标签训练数据的获取往往需要耗费较⼤的⼈⼒和物⼒。如何利 ⽤主动学习获取训练数据以降低研究代价,是当前学术界和⼯业界研究的热点话题。
下面是如何在 Python 中使用 LSTM 模型对一元时间序列数据进行预测的例子: 首先,我们需要导入必要的库和数据集。这里我们使用了 Keras 库和一个名为 "AirPassengers" 的经典时间序列数据集,该数据集记录了 1949 年到 1960 年之间每月的乘客数量。 ```python import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error from matplotlib import pyplot as plt # load the dataset dataset = np.array([112,118,132,129,121,135,148,148,136,119,104,118, 115,126,141,135,125,149,170,170,158,133,114,140, 145,150,178,163,172,178,199,199,184,162,146,166, 171,180,193,181,183,218,230,242,209,191,172,194, 196,196,236,235,229,243,264,272,237,211,180,201, 204,188,235,227,234,264,302,293,259,229,203,229, 242,233,267,269,270,315,364,347,312,274,237,278, 284,277,317,313,318,374,413,405,355,306,271,306, 315,301,356,348,355,422,465,467,404,347,305,336, 340,318,362,348,363,435,491,505,404,359,310,337, 360,342,406,396,420,472,548,559,463,407,362,405, 417,391,419,461,472,535,622,606,508,461,390,432]) ``` 接下来,我们需要对数据进行预处理,将其归一化并将其转换为适合 LSTM 处理的格式。这里我们使用 MinMaxScaler 类来进行归一化处理。 ```python # normalize the dataset scaler = MinMaxScaler(feature_range=(0, 1)) dataset = scaler.fit_transform(dataset.reshape(-1, 1)) # split into train and test sets train_size = int(len(dataset) * 0.67) test_size = len(dataset) - train_size train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:] ``` 然后,我们需要将数据转换为适合 LSTM 模型处理的格式。LSTM 模型期望输入序列数据的格式为 [样本数,时间步数,特征数]。在这里,我们将数据转换为一个二维数组,其中第一列包含当前时间步的乘客数量,第二列包含下一个时间步的乘客数量。 ```python # convert an array of values into a dataset matrix def create_dataset(dataset, look_back=1): dataX, dataY = [], [] for i in range(len(dataset)-look_back-1): a = dataset[i:(i+look_back), 0] dataX.append(a) dataY.append(dataset[i + look_back, 0]) return np.array(dataX), np.array(dataY) # reshape into X=t and Y=t+1 look_back = 1 trainX, trainY = create_dataset(train, look_back) testX, testY = create_dataset(test, look_back) # reshape input to be [samples, time steps, features] trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1])) ``` 现在,我们可以使用 Keras 库构建 LSTM 模型。在这里,我们使用一个单层 LSTM 模型,其中有 4 个 LSTM 单元和一个密集层,用于输出预测值。我们还使用了均方误差损失函数和 Adam 优化器。 ```python # create and fit the LSTM network model = Sequential() model.add(LSTM(4, input_shape=(1, look_back))) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=2) ``` 最后,我们可以使用训练好的模型进行预测,并计算预测值与实际值之间的均方根误差。 ```python # make predictions trainPredict = model.predict(trainX) testPredict = model.predict(testX) # invert predictions trainPredict = scaler.inverse_transform(trainPredict) trainY = scaler.inverse_transform([trainY]) testPredict = scaler.inverse_transform(testPredict) testY = scaler.inverse_transform([testY]) # calculate root mean squared error trainScore = np.sqrt(mean_squared_error(trainY[0], trainPredict[:,0])) print('Train Score: %.2f RMSE' % (trainScore)) testScore = np.sqrt(mean_squared_error(testY[0], testPredict[:,0])) print('Test Score: %.2f RMSE' % (testScore)) ``` 最后,我们可以绘制训练集和测试集的预测结果与实际结果之间的比较图。 ```python # shift train predictions for plotting trainPredictPlot = np.empty_like(dataset) trainPredictPlot[:, :] = np.nan trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict # shift test predictions for plotting testPredictPlot = np.empty_like(dataset) testPredictPlot[:, :] = np.nan testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict # plot baseline and predictions plt.plot(scaler.inverse_transform(dataset)) plt.plot(trainPredictPlot) plt.plot(testPredictPlot) plt.show() ``` 这样就可以使用 LSTM 模型对一元时间序列数据进行预测了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月满闲庭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值