2024年3月

前言:


CYQ.Data
版本更新的这么多年,中间过程的版本都在完善各种功能。

基于需要支持或兼容的代码越多,很多时候,常规思维,都把相关功能完成,就结束了。

实现过程中,无法避免的会用到大量的反射、锁等对性能有所影响的逻辑代码。

CYQ.Data 从V5.9 版本开始,开始大规模的优化调整代码,目前稳定在 V5.9.2.7 版本,下面看一下更新记录

版本更新记录:

794:新增:FireBird 数据库支持:增删改查与分页。(2023-12-18)【V5.9.0.0 - V5.9.0.2795:新增:DaMeng 达梦数据库支持:增删改查与分页。(2023-12-20796:优化:FireBird 数据结构获取与转化的精准化。(2023-12-21797:优化:DaMeng 数据结构获取与转化的精准化。(2023-12-22798:新增:DaMeng : AppConfig.DB.IsDaMengUpper 配置,默认表名字段转大写。(2023-12-23799:新增:FireBird:AppConfig.DB.IsFireBirdUpper 配置,默认表名字段转大写。(2023-12-23800:优化:Postgre: AppConfig.DB.IsPostgreLower 配置,默认表名字段转小写。(2023-12-23801:新增:KingBaseES 人大金仓数据库支持:增删改查与分页。(2023-12-24802:优化:KingBaseES 数据结构获取与转化的精准化。(2023-12-25803:优化:CYQ.Data.Orm.SimpleOrm 基类。(2024-01-01804:新增:分布式锁类:DistributedLock。(2024-01-02805:优化:调整注意:CacheManage 名称变更分布式缓存:DistributedCache。(2024-01-04806:优化:调整注意:JsonHelper 名称空间由CYQ.Data.Tool 变更为:CYQ.Data.Json。(2024-01-04807:优化:增加输出标准库:.net standard2.1 版本。(2024-01-10-------------------------------------------------------------------------------------
808:优化:AppConfig.WebRootPath 路径的获取。(2024-01-13)【V5.9.0.3809:优化:SimpleOrmBase(2024-01-13810:优化:增加 AppConfig.IsDebugMode 只读属性,优化 WebRootPath 属性取值。811:优化:内部IP获取。-------------------------------------------------------------------------------------
812:修复:AppConfig.IsDebugMode .net 下取值。(2024-01-21)【V5.9.0.4813:新增:分布式锁增加幂等性方法。(2024-01-21814:修复:V5.9.0.3优化的内部IP获取,在Docker容器不支持的异常。 【V5.9.0.5-------------------------------------------------------------------------------------
815:优化:XHtmlAction 加载 html 速度,无实体&xxxx;内容时不加载dtd。(2024-01-25)【V5.9.0.6816:优化:AppConfig:IsNetCore 和 IsWeb 和 WebRoot 三个属性取值。(2024-01-25817:移除:【分布式锁】转移到 Taurus.DistributedLock 插件库中(增加数据库锁)。(2024-01-25818:优化:SimpleOrmBase 增加构造函数重载,允许异常时不写日志【以支持分布式数据库锁】。(2024-01-26819:优化:AppConfig 调整几个不常用的配置项【DefaultCacheTime、IsEnumToInt、JsonEscape】。(2024-01-26820:优化:DistributedCache 开放几个批量接口,以供分布式锁插件调用。(2024-01-27821:修复:SimpleOrmBase 构造函数忘了赋值链接。(2024-01-29)【V5.9.0.7-------------------------------------------------------------------------------------
822:优化:XHtmlAction 加载性能:优化缓存转化,提升2次访问速度。(2024-01-31)【V5.9.1.0823:优化:XHtmlAction 加载性能:优化取消DTD依赖、提升首次访问速度。(2024-02-01-------------------------------------------------------------------------------------
824:优化:XHtmlAction 调整方法或属性:SaveToCache 更名为RefleshCache 等。(2024-02-04)【V5.9.1.1825:移除:IField 扩展。(2024-02-04826:优化:MDataRow GetIndex,提升取值性能。(2024-02-04827:优化:ConvertTool 相关方法,提升转化性能。(2024-02-04-------------------------------------------------------------------------------------版本简要:通过大范围使用 Emit 来替换反射,提升性能。828:新增:CYQ.Data.Emit(内部)优化反射代码,提升性能。【V5.9.2829:新增:JsonOp 参数,调整(JsonHelper、MDataRow、MDataTable)ToJson 重载方法参数。(2024-02-06830:优化:JsonHelper 实体转化性能:涉及:ToJson(),ToList<T>()。(2024-02-052024-02-22831:优化:MDataTable 实体列表转化性能:涉及:CreateFrom。(2024-02-22832:优化:MDataRow 实体转化性能:涉及:CreateFrom。。(2024-02-22-------------------------------------------------------------------------------------版本简要:对 XHtmlAction 进行各种简化和优化,以供 Taurus.Mvc 便于使用。833:移除:XHtmlAction SetFor 系列方法(该方法使用门槛较高) 。(2024-02-23)【V5.9.2.1834:移除:XHtmlAction SetForeach(MDataTable dataSource, string idOrName, SetType setType) 重载方法 。(2024-02-23835:移除:XHtmlAction GetByID,GetByName 两个方法,其 Get 方法已可替代以上两者。(2024-02-23836:移除:XHtmlAction IsCurrentLang,IsUseLangSplit 两个成员属性。(2024-02-23837:移除:XHtmlBase LoadFromCache、SetCDATA、ClearCDATA 等方法。838:优化:XHtmlAction SetForeach 方法优化,支持绑定其它数据源。(2024-02-23839:优化:XHtmlAction LoadData 方法优化,效果变更为批量对KeyValue赋值。(2024-02-23840:优化:XHtmlAction 加载:去除 http://www.w3.org/1999/xhtml 名称空间。2024-02-24)【V5.9.2.2】
-------------------------------------------------------------------------------------版本简要:持续优化,提升性能。840:优化:ConvertTool、ReflectTool 相关方法。(2024-02-26)【V5.9.2.3841:优化:MDataRow Load(json)。(2024-02-26842:优化:MDataTable ToList(t) 内部方法。(2024-02-26845:优化:JsonHelper(2024-02-27-------------------------------------------------------------------------------------
846:变更:将 AppConfig 中的一些和配置无关的只读属性转移到AppConst中。(2024-02-29)【V5.9.2.4847:移除:LocalEnvironment 内部类。(2024-02-29848:优化:ConvertTool.ChangeReaderToList<T> 内部类。(2024-02-29849:新增:开放:CYQ.Data.Emit.EmitPreheat 类,允许处理 Emit 委托预热。(2024-02-29-------------------------------------------------------------------------------------版本简要:针对 Taurus.MVC 进行全方位细节进行性能优化。【V5.9.2.6850:新增:HttpRequest 扩展方法:GetHeader、GetForm、GetQuery、GetCookie 等。(2024-03-04851:优化:XHtmlAction OutXml 等多项细节优化。(2024-03-05-------------------------------------------------------------------------------------
852:新增 HttpPostedFileCreator.Create 用于创建 HttpPostedFile 实例。(因 Taurus RpcProxy 添加)(2024-03-07)【V5.9.2.7853:新增:开放几个和实体转换相关的 Emit 接口。(2024-03-08854:修正:JsonHelper.ToJson 未处理 IgnoreJson 属性标记的问题、其它优化。(2024-03-08

优化简介:

在整个优化过程,主要分为:

1、逻辑优化:

通过逻辑优化,减少代码执行。

2、减少中间商:

在过往版本,MDataTable 和 MDataRow 做为中间人,承载着所有类型转换。

通过编写直接转换,不再通过中间人进行转换,减少转换的环节。

3、Emit 代替反射:

在类型转换中,无可避免的大量的使用了反射。

为了替代大量的反射,因此编写了大量的Emit,导致工作量有点大,但为了性能,这无可避免。

4、减少锁:

在内部中,有大量用到MDicationary来缓存数据,这是一个自定义实现的线程安全的带锁的字典,曾经优化过一次,将通用锁拆分成了读写锁。

在减少锁的过程中,对于无需要 Remove 操作或 Foreach 遍历的全局数据缓存字典,将 MDicationary 换成 Dicationary,避开锁机制,对并发场景下引发的 Add 异常进行
try

5、并行执行:

对于数据量大的场景,分拆成多线程并行执行。

下面就来重新看一下新的测试结果:

测试环境:

本次测试为.Net Windown 版本,下次再测试.Net Core Linux 版本。

Win11 系统:6核16G内存

测试代码,基础实体类:

public classSimpleEntity
{
public int ID { get; set; }public Guid MsgID { get; set; }public string Name { get; set; }public bool IsEnable { get; set; }public DateTime CreateTime { get; set; }
}

本次测试结果仅供参考

性能测试对比:

1、实体类转Json(执行4次):

2、实体类列表(100条)转Json(执行4次):

3、Json 转 Dictionary<,> (执行4次)

4、Json 转 实体类(执行4次)

5、Json 转 实体类列表100条数据 (执行4次)

测试结果总结:

1、在首次执行时,CYQ.Data 全面超过了 Newtonsoft.Json,差距明显,说明 Newtonsoft.Json 首次执行,性能较低,在预热这一块没有优化好。

2、在 Json 转 Dictionary 方面,CYQ.Data 有全面的优势,超过 Newtonsoft.Json。

2、在其它转换的在后续执行中,Newtonsoft.Json 和 CYQ.Data 差距不大,基本持平。

总结:

曾经有人和我说过,CYQ.Data 在 Json 这一块的转换性能不强,后来换了 Newtonsoft.Json 去操作 Json 。

那时候可能时机不成熟,要优化,需要重写的代码太多了,所以就没怎么处理。

直到今年,有个老田同学他自己写框架了,问了个他框架调用异步方法无法 try 到异常的问题:

秋天您好,请教您一个问题,您在做框架的时候是如何实现async的异常捕捉和处理的,我这里支持async的方法后反射到controller里的方法无法正常捕捉到异常,抛出自定义异常会让整个线程挂掉。

后来这问题解决了之后,我翻了下历史聊天记录,发现它曾经建议我在Taurus里把方法的反射换成委托。

从这里开始,开启了
Taurus.MVC
框架的全面优化。

然后就涉及做为底层组件的 CYQ.Data,将它进行了全面的性能优化大整改。

于是便有了如今性能优越的版本。

AES算法起源:

AES(Advanced Encryption Standard)算法是一种对称密钥加密算法,由比利时密码学家Joan Daemen和Vincent Rijmen设计,于2001年被美国国家标准技术研究所(NIST)确定为新的数据加密标准。AES算法取代了DES算法,成为当前最流行的对称加密算法之一。

AES算法原理:

  1. 密钥扩展
    :根据初始密钥生成多个轮密钥。
  2. 初始轮密钥加
    :将明文与第一轮密钥进行异或操作。
  3. 轮函数
    :包括字节替代、行移位、列混淆和轮密钥加。
  4. 多轮迭代
    :经过多轮迭代,每轮使用一个轮密钥。
  5. 最终轮
    :最后一轮不包括列混淆,最终输出密文。

AES算法优缺点:

优点

  • 安全性高,经过广泛验证和应用。
  • 高效性好,速度快,适用于各种平台和设备。

缺点

  • 密钥管理较复杂,需要安全地存储和传输密钥。
  • 可能受到侧信道攻击等攻击方式影响。

AES算法与其他算法对比:

  • 与DES算法相比
    :AES算法更安全、更高效,密钥长度更长,抗暴力破解能力更强。
  • 与RSA算法相比
    :RSA算法适用于非对称加密,用于数字签名和密钥交换。

AES算法解决问题的技术:

  1. AES-GCM
    :结合加密和认证,提供完整的数据保护。
  2. AES-NI指令集
    :利用硬件加速,提高AES算法的性能。

Python示例:

python
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

key = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_ECB)

message = b'Hello, AES!'
ciphertext = cipher.encrypt(message)
print("Encrypted:", ciphertext)

decipher = AES.new(key, AES.MODE_ECB)
decrypted = decipher.decrypt(ciphertext)
print("Decrypted:", decrypted.decode())

JavaScript示例:

javascript
const crypto = require('crypto');

const key = crypto.randomBytes(16);
const iv = crypto.randomBytes(16);

const cipher = crypto.createCipheriv('aes-128-ecb', key, null);
let encrypted = cipher.update('Hello, AES!', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log("Encrypted:", encrypted);

const decipher = crypto.createDecipheriv('aes-128-ecb', key, null);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log("Decrypted:", decrypted);

总结:

AES算法作为当前最流行的对称密钥加密算法,具有高安全性和高效性的特点,被广泛应用于信息安全领域。AES算法通过密钥扩展、轮函数和多轮迭代等步骤实现数据加密和解密,保护数据的机密性。尽管AES算法在安全性和性能方面表现优异,但仍需注意密钥管理和可能的侧信道攻击等问题。为了提高数据保护的全面性,可以采用AES-GCM等结合认证和加密的技术,或者利用AES-NI指令集来提高算法性能。AES算法的应用将继续在信息安全领域发挥重要作用,为数据传输和存储提供可靠的保障。

转载请注明出处:
https://www.cnblogs.com/zhiyong-ITNote

参考现有的中文医疗模型:
MedicalGPT

CareGPT
等领域模型的训练流程,结合ChatGPT的训练流程,总结如下:
在预训练阶段,模型会从大量无标注文本数据集中学习领域/通用知识;其次使用{有监督微调}(SFT)优化模型以更好地遵守特定指令;最后使用对齐技术使LLM更有用更安全的响应用户的提示。

训练流程的四个阶段,分别如下:

  1. 预训练(pre-training,pt),基于基座模型,经过海量中文医疗预料训练,得到领域适配的ChatGLM-6B。
  2. 监督微调(supervised finetuning,sft),通过在线问诊等数据,构建训练数据完成指令微调。
  3. RM模型构建(reward modeling, rm),人工对预测答案排序,训练一个打分模型
  4. 强化学习阶段(reinforcement learning, rl),基于PPO算法,采用RL的方式,完成fine-tuned ChatGLM-6B模型的优化。

预训练阶段-PT

该阶段的训练数据格式如下。对应是非结构化的自然语言文本,通过设定max_seq_len和block_size等方式,实现文本数据的chunk,batch化,作为模型的训练数据,处理完的单条数据包含input_ids,attention_mask和labels;训练的目标是模型需要根据提供的文本来预测 下一个单词。
image.png

监督微调阶段-SFT

该阶段的训练数据格式如下。一般对应的结构采用instruction/input/output/history,根据不同的场景,input与history可以做缺省处理。但是需要人工标注的指令数据集。
image.png

对齐

该阶段的主要目标是将语言模型喻人类的偏好、价值观进行对齐,这也是RHLF机制的作用。
RLHF主要包括两步:

  1. 基于有监督微调模型基础上创建一个reward model(RM)模型;
  2. 基于RM模型使用PPO/DPO算法微调SFT模型,返回最佳response。

奖励模型-RM

该阶段是RHLF的第一个阶段,训练得到一个rm模型用于rl阶段的模型打分,其结构格式如下:
image.png
image.png
有多种格式的数据,可自己选择,但需要程序做额外的处理,且这些数据都是人工标注好的。

强化学习-RL

该阶段是RHLF的第二个阶段,也是核心部分,用于优化一个RM模型,并完成打分。数据格式同SFT。一般在此阶段会使用特定的算法(DPO/PPO)来实现;引导优化后的大模型生成更符合人类偏好的内容。

总结

对于模型的微调,一开始我是想的太简单了,觉得只要按照基座官方模型文档调试即可;随着了解的深入与不断的学习,微调是个大工程而且对于领域模型来说,其训练流程:预训练 --> 监督微调 --> RHLF 中包含的事项与知识太多。
参考:
【中文医疗大模型】训练全流程源码剖析

转载请注明出处:
https://www.cnblogs.com/zhiyong-ITNote

首发于个人公众号
image

本文分享自华为云社区《
画图实战-Python实现某产品全年销量数据多种样式可视化
》,作者:虫无涯。

学习心得

  • 有时候我们需要对某些数据进行分析,得到一些可视化效果图,而这些效果图可以直观展示给我们数据的变化趋势;

  • 比如某产品的月销量数据、销售额的地区分布、销售增长和季节的变化情况、产品的贡献度分析等等;

  • 本文主要针对某产品全年销量数据,绘制各种不同样式的图表,以不同样式展示数据;

  • 学习本文建议对Python的matplotlib第三库有一定的了解。

Matplotlib说明

什么是Matplotlib?

  • Matplotlib是一个Python的2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形;

  • Matplotlib可生成绘图、直方图、功率谱、条形图、错误图、散点图、折线图等;

  • Matplotlib是Python生态系统的一个重要组成部分,是用于可视化的绘图库;

  • Matplotlib提供了一整套和matlab相似的命令API和可视化界面,可以生成出版质量级别的精美图形。

Matplotlib特性

  • Matplotlib图表中的元素包含以下内容:

A、X轴和Y轴;B、X轴和Y轴刻度;C、X轴和Y轴标签;D、绘图区域。

  • 关于hold属性:

A、hold属性默认为True,可在一幅图中绘制多个曲线;B、将hold属性修改为False,每一个plot都会覆盖前面的plot(这种方法不推荐,建议使用默认的)。

  • 常用方法:

A、可使用grid方法为图添加网格线;B、还可以使用其他方法,如axis方法、xlim方法、ylim方法、legend方法;

  • 关于配置方面:

matplotlib配置信息是从配置文件读取的。在配置文件中可以为matplotlib的几乎所有属性指定永久有效的默认;主要为永久配置和动态配置。

Matplotlib安装

直接使用pip安装即可:

pip install matplotlib

产品订单量-折线图

某产品全年订单量数据

  • 以下是某产品全年的销量数据:

  • 全年12个月数据中,每个月对应有产品的订单量和退货量。

数据提取和分析

  • 我们可以把月份用以下变量表示:

month = ["Jan", "Feb", "Mar", "Apr","May", "Jun", "Jul", "Aug","Sep", "Oct", "Nov", "Dec"]

print(f
"月份为:{month}")
# 输出:月份为:[
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

复制运行

  • 产品对应的销量分两种,一种是订单量,一种是退货量,可用两个变量来存放数据:

# 订单量
indent
= [15, 33, 42, 50, 115, 20, 86, 66, 59, 43, 39, 50]

# 退货量
returned
= [6, 13, 18, 23, 55, 98, 42, 31, 25, 22, 17, 24]

print(f
"每月订单量为:{indent}")
print(f
"每月退货量为:{returned}")

绘制折线图

  • 折线图中我们绘制两条折线,一条是每月的退货量,一条是每月的订单量;

  • 而折线就是坐标组成,这里就需要多个两个坐标,比如x1、y1、x2、y2;

  • 针对我们提供的数据,可以把坐标定义为:

x1 = month y1 = indentx2= month y2 = returned

  • 那对应的代码为:

import subprocess
import sys
subprocess.check_call([sys.executable,
"-m", "pip", "install", "matplotlib"])
import matplotlib.pyplot
asplt

month
= ["Jan", "Feb", "Mar", "Apr","May", "Jun", "Jul", "Aug","Sep", "Oct", "Nov", "Dec"]
print(f
"月份为:{month}")

# 订单量
indent
= [15, 33, 42, 50, 115, 20, 86, 66, 59, 43, 39, 50]

# 退货量
returned
= [6, 13, 18, 23, 55, 98, 42, 31, 25, 22, 17, 24]
print(f
"每月订单量为:{indent}")
print(f
"每月退货量为:{returned}")

# 绘制折线图
plt.plot(month, indent, label
='订单量',
linewidth
=2, color='r', marker='o',
markerfacecolor
='blue', markersize=8)

plt.plot(month, returned, label
='退货量',
linewidth
=2, color='y', marker='o',
markerfacecolor
='blue', markersize=8)

plt.xlabel(
'月份')
plt.ylabel(
'数量')
plt.title(
'某产品全年订单销售情况')
plt.rcParams[
'font.sans-serif'] = ['SimHei']
plt.legend()
# plt.show()
plt.savefig(
"plot.jpg")
  • 运行上边代码后折线图的效果为:

请在此添加图片描述

产品订单&销售额-条形图

某产品全年订单&销售额数据

  • 以下是某产品全年的销量数据:

  • 图中的意思为对应的订单量的销售额和对应的退货量的价格。

绘制条形图

  • 条形图中我们绘制双条形,一条是每月的退货量及对应价格,一条是每月的订单量和销售额;

  • 针对我们提供的数据,可以把坐标定义为:

x1 = indent y1 = m1x2= returned y2 = m2

  • 那对应的代码为:

import subprocess
import sys
subprocess.check_call([sys.executable,
"-m", "pip", "install", "matplotlib"])
import matplotlib.pyplot
asplt

# 订单量
indent
= [10, 30, 50, 70, 90, 110, 130, 150]
# 销售额
m1
= [5, 7, 9, 11, 13, 15, 17, 19]

# 退货量
returned
= [20, 40, 60, 80, 100, 120, 140, 160]
# 价格
m2
= [3, 5, 7, 9, 11, 13, 15, 17]

# 绘制折线图
plt.bar(indent, m1, width
=3, label='订单量-销售额', color='r', )
plt.bar(returned, m2, width
=3, label='退货量-价格', color='y')

plt.xlabel(
'数量')
plt.ylabel(
'价格')
plt.title(
'某产品全年订单&销售额情况')
plt.rcParams[
'font.sans-serif'] = ['SimHei']
plt.legend()
# plt.show()
plt.savefig(
"plot.jpg")
  • 运行以上代码后效果图为:

请在此添加图片描述

注意:后续的数据和操作逻辑和前边的一样,为了快速了解其使用,不再描述详细的数据,仅用示例说明。

某产品xx-直方图

  • 那对应的代码为:

import subprocess
import sys
subprocess.check_call([sys.executable,
"-m", "pip", "install", "matplotlib"])
import matplotlib.pyplot
asplt

data
= [15, 33, 42, 50, 115, 20, 86, 66, 59, 43, 39, 50]
x
= range(0, 100, 2)

# 绘制直方图
plt.hist(data, x, rwidth
=3, label='直方图', color='y')

plt.xlabel(
'X')
plt.ylabel(
'Y')
plt.title(
'直方图')
plt.rcParams[
'font.sans-serif'] = ['SimHei']
plt.legend()
# plt.show()
plt.savefig(
"plot.jpg")
  • 运行代码后效果如下:

请在此添加图片描述

某产品xx-散点图

  • 那对应的代码为:

import subprocess
import sys
subprocess.check_call([sys.executable,
"-m", "pip", "install", "matplotlib"])
import matplotlib.pyplot
asplt

data
= [15, 33, 42, 50, 115, 20, 86, 66, 59, 43, 39, 50]
x
= range(0, len(data))

# 绘制散点图
plt.scatter(x, data, label
='散点图', s=15)

plt.xlabel(
'X')
plt.ylabel(
'Y')
plt.title(
'散点图')
plt.rcParams[
'font.sans-serif'] = ['SimHei']
plt.legend()
# plt.show()
plt.savefig(
"plot.jpg")
  • 运行代码后效果为:

请在此添加图片描述

某产品xx-饼图

  • 对应代码为:

import subprocess
import sys
subprocess.check_call([sys.executable,
"-m", "pip", "install", "matplotlib"])
subprocess.check_call([sys.executable,
"-m", "pip", "install", "numpy"])
import matplotlib.pyplot
asplt
import numpy
asnp

data
= np.array([10, 20, 15, 15, 5, 5, 30])

plt.pie(data,
labels
=['P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7'],
colors
=["#8B008B", "#FF1493", "#4B0082", "#B0C4DE", "#E1FFFF", "#008080", "#00FF7F"],
explode
=(0, 0, 0.3, 0, 0, 0.2, 0),
autopct
='%.2f%%',
)
plt.title(
'饼图')
plt.rcParams[
'font.sans-serif'] = ['SimHei']
# plt.show()
plt.savefig(
"plot.jpg")
  • 运行代码效果为:

请在此添加图片描述

某产品xx-多图效果

  • 对应代码为:

import subprocess
import sys
subprocess.check_call([sys.executable,
"-m", "pip", "install", "matplotlib"])
subprocess.check_call([sys.executable,
"-m", "pip", "install", "numpy"])
import matplotlib.pyplot
asplt
import numpy
asnp

x
= np.array([10, 50])
y
= np.array([10, 80])
plt.subplot(
2, 2, 1)
plt.plot(x, y)
plt.title(
"图1")

x
= np.array([10, 20, 30, 40])
y
= np.array([10, 30, 50, 110])
plt.subplot(
2, 2, 2)
plt.plot(x, y)
plt.title(
"图2")
x
= np.array([10, 20, 30, 40])
y
= np.array([50, 60, 70, 80])
plt.subplot(
2, 2, 3)
plt.plot(x, y)
plt.title(
"图3")
x
= np.array([20, 25, 30, 35])
y
= np.array([40, 45, 50, 55])
plt.subplot(
2, 2, 4)
plt.plot(x, y)
plt.title(
"图4")

plt.suptitle(
"多图显示")
plt.rcParams[
'font.sans-serif'] = ['SimHei']
#plt.show()
plt.savefig(
"plot.jpg")
  • 运行代码后的效果为:

请在此添加图片描述

总结

Python实现某产品全年销量数据多种样式可视化,主要是应用了python的matplotlib库进行绘制各种图表,除了以上的几种图表,还有柱状图、网格图等等。学习的时候建议使用真实的数据,可以真正达到分析问题的效果。

点击关注,第一时间了解华为云新鲜技术~

上次在公司的Windows7电脑上操作系统没有自动进行校时,导致系统时间老是快那么几分钟,于是想到了用C#开发一个系统时间自动校时器。这个应用不难,主要是能够校时那个操作类的问题。

1、
项目目录;

2、
源码介绍;

1) 主窗体;

2) 进行校时的操作;

3、
运行界面;

1) 提示窗体;

2) 菜单;

4、
使用介绍;

直接运行该应用即可,使用起来很方便,如果重复打开该应用,则会立即进行校时操作。

5、
源码下载;

提供源码下载:
https://download.csdn.net/download/lzhdim/88967465

6、
其它建议;

项目只开发到这,默认用的是time.windows.com这个域名的IP地址去进行的校时,其它的IP目前还没实现,请读者自己去将该方案进行实现吧。

目前笔者有开发相关的C#的应用,这个校时器只是其中之一,请感兴趣的读者翻一下笔者的这些个小作品系列:
https://www.cnblogs.com/lzhdim/category/703308.html