|
! ~5 R6 ^9 g) @- ?6 L- y1 B 最近一段时间,工作上花了不少时间用MATLAB处理工厂下线的数据,数据庞大不说,复杂度也高,各种推算和统计 " F* {; b e0 A; N+ ]- X2 ?7 i
所以今天我打算总结一下,平时我在用MATLAB做数据分析时常用的几个小技巧 / r0 q$ t5 u0 P# [7 |
正好全国大学生数学建模竞赛下周就要开始了,希望今天的分享对参赛的朋友有所帮助 ! H' H' v2 _# k! c) s& C+ a( a4 T
虽然不知道到时候会有哪些选题,但是能肯定的是,不管是什么题目,都离不开数据分析,这是唯一比赛前能好好准备的 ' R8 y& I/ E3 H4 {
1. 数据类型的转换
: z: X: y# l- N8 j' [$ N5 A5 J5 |+ z* e 有一类问题,不论你MATLAB水平如何,平时写代码的时候多少总会遇到,就是数据类型不一致,需要转换 5 s: n6 ~5 n' @" A
至于什么是数据类型,这个问题我就不科普了,大家可以直接在MATLAB命令栏“doc 数据类型” 6 I+ E+ o: ~7 D
: n, d( `: E1 h4 N 通常在数据转换这个问题上,涉及到的比较常见几种的数据类型有double,char,cell,struct
, l3 K0 [9 b3 T% j0 w6 f0 z 我给大家准备了一张数据类型转换的关系图,用class判断一下转换前的两种数据类型,然后按照下面这张图处理就完事了 8 v0 E" w! D, A5 ?
: T0 z# Y* p% d( _ 2. 字符串的对比 # m2 d. J$ M+ E8 R/ a, H
第二个经常需要处理的问题是,字符串的对比 9 {0 B* c' z+ j: b/ y' w9 N
这里不单单指的是字符串,还包括cell元胞里面的字符串定位 5 k2 G0 z# q/ O L6 d0 c
如果单纯只是字符串的话,要判断两个字符串是否相同,strcmp函数可以实现对比
8 x+ q" a8 P. d% |) G: Z strcmp(abc,abc) ; s3 u) }7 Y1 |5 M
判断字符串中是否包含某种字符串,可以使用contains函数
/ ~, O/ S5 w- m3 ~" r contains(abc,ab)
0 M0 D( Z% T& A/ Q5 \* y5 U 判断字符串中在哪几位出现某种字符串,可以使用regexp函数
. r/ t8 l# b7 X4 [) L9 A. f- n7 o/ ? regexp(abac,a) 9 I* b5 g$ x% j. K
更常碰到的场景是,在cell元胞里面判断字符串,比如维度1x1000的cell中,定位哪几个cell里面的字符串是‘abc’,还是通过strcmp实现对比,再通过find定位 ) F! N2 O* s- _8 v6 l) ?
a = strcmp(Cell_variable,abc);+ E! G5 h. C; j/ U& c! X
b = find(a == 1)
9 [3 B; y5 c* h; o8 \3 x 同样,要判断这1x1000的cell中,定位哪几个cell中的字符串,带有‘ab’,可以使用contains函数,再用find定位 " B# g. N) M, R+ }
a = contains (Cell_variable,ab);
7 d! C, p" M/ l: } b = find(a == 1)
) i: L* C$ h' d, @ H2 J) k 掌握上面这两点,在平时处理cell的字符串,基本上就够用了 5 l2 f: ~- n) Q1 ~" `+ o
3. 文件的读取写入 ; h( \! d; a& [, M
文件的读取写入同样非常重要,在数据分析过程中,对应着信息的获取和数据处理结果的输出 2 T: N3 r; v/ r4 A f' O
mat, txt, excel是平时最常碰到的文件类型 . J" p9 u0 q+ d: |
mat就不用多说了,MATLAB中的一种文件类型,用于存储workspace中的变量,在数据分析过程中,可以经常把运算结果或中间阶段的数据,作为mat进行保存
' i) W" t2 D* L/ @* F 加载mat文件,用的是“load 文件名”命令,也可以双击mat文件,保存mat文件,用的是“save 文件名”命令,也可以workspace右键保存 4 y# h c' @" n5 x
txt的读取方式有非常多,网上也有各种各样的介绍,我就介绍两种最常用,也是目前我一直在用的两种方法 . h7 D1 ]- s, m5 R% H( ~6 F+ g
第一种是通过importdata(‘test.txt’)命令,读取的结果是一个多行一列的cell元胞,后续的数据处理也就方便了,cell里面的字符串定位处理在前面也已经介绍过
) H/ I/ N( M+ L6 }) B8 r6 q 另一种方法是,通过MATLAB工具条里的“导入数据”按钮,这种方法的一个好处是,导入过程中有很多非常人性化的设置,比如数据的分隔,范围定义,数据的输出类型等等
7 D; B+ e4 S! J0 c H/ \ 导出的选择也有不少,可以选择直接导出到workspace,也可以选择生成脚本或者是function,方便同类型文本的重复使用,对于不太喜欢写脚本导入数据的朋友,我比较推荐这种方式
- p" x( `7 }- N% S , o U) a$ p) g- c+ S
3 l8 O$ z* a- S9 g3 b ) b6 k* l" v1 R) a0 V
txt的写入,可以通过fopen,fprintf,fclose实现,基本上我所有GUI中关于代码生成的功能,都是通过这个方式将代码写入m脚本的,给大家举一个简单的txt写入的例子代码 * e3 {1 y) a2 J- Y
fid = fopen(test.txt,wt);$ o' [8 p! @! n
fprintf(fid,test1\n);
8 K. \3 M) ?( m3 S fprintf(fid,test2\n);2 B. }# C/ P% x1 G- \
fclose(fid);
: c0 X! m" \7 Z$ `: c 关于txt的读取写入,我再多介绍一点,txt是文本文件中的一种,就是那种右键打开能读得懂的文件。类似的文本文件还有很多,像m文件,mdl模型文件,dcm文件,c代码等等,只要是文本文件,都可以用txt处理的方式,对目标文件进行读取写入。
# Z; `9 ~+ }1 U0 ] 最后讲一下Excel读取写入的问题,常写MATLAB脚本的朋友,对xlsread和xlswrite肯定不陌生,对应的是Excel的读取和写入 . e, W9 v" }9 q3 K8 f1 @
[num,txt,raw] = xlsread(filename,sheet,xlRange)3 ~5 {3 Z4 g% x9 Q
xlswrite(filename,A,sheet,xlRange) 1 N' i; }$ x. J5 q: v9 A& O
但是目前MATLAB官方已经不推荐使用这两种方式了,替代的函数是readtable和writetable , {2 o2 I, G' @+ x
T = readtable(filename)
% v, i3 J9 H; z! n. o+ e' |8 ] writetable(T,filename)
2 U# R9 u7 x3 N* m; u7 G
4 Z7 @/ x8 U$ E* E. | 如果数据是cell元胞的话,替代的函数是readcell和writecell
+ Q" n: G7 [# Y7 [+ j# u, Z T = readcell(filename)* Y+ {! ]; o9 |" `( E0 a5 ]
writecell(T,filename) 0 N7 G7 D; p% _5 @
大家根据自己的个人习惯选择其中一种方式,两种方式在功能实现上目前并没有太大区别
, ]4 F2 l, P. S" a* a+ H 4. 数据可视化 ! d5 U- A6 U3 W) b$ l, w
数据可视化,结果的呈现,也是数据分析过程中至关重要的一环 2 G# C& g& x8 G5 [2 H
像大家非常熟悉的函数plot,就可以用来画曲线图,但是有时候仅仅曲线图并不足以来呈现结果,还需要用到比如像三维图,柱状图,饼状图,蜡烛图等等 6 ~1 ~4 k. n. n+ g& S8 N' F
这部分我并不打算给大家罗列各种图形对应代码命令,大家也没必要刻意地去死记这些代码,安利一个非常通用的方法
/ F% q' ^7 g5 O+ O8 z8 o5 j( z 在选择需要可视化的数据之后,在MATLAB工具条的绘图窗口,选取你喜欢的图形,就能生成你需要的结果图了
: t. d3 T2 s. k' } ; r, e* l% i' R/ S
不过,至于图片的细节,像title,legend,网格,还是需要自己微调,但这都不是事,再安利大家一个简单的方法,完全不用上网去搜 # C5 m7 h+ D7 \$ M6 ~' V
在生成窗口中,点击属性检查器,然后根据自己的需要完善图片的细节,最后通过生成代码,就能看到这部分作图操作的原始代码了,大家也能在代码的基础上再微调,或者复用
% L1 j! W; I0 |- k* s- I
$ i2 [; {' t. ]" u
}4 f t2 D: [9 i! g) R% | / D/ Z; V3 }3 Z! a, p3 I1 g
5. 数据处理的常用函数 0 D, G* v6 r7 O& e% k, Q# d
关于数据处理的函数,像max,min,mean,std这些函数都是比较常用的函数,分别是最大值,最小值,平均值,标准差 5 o# t! V+ X8 O& O3 F" b/ W# R* h
再安利大家几个平时我在处理数据时最常用的几个函数
% a( g. x, e5 A4 v0 R 第一个是unique函数,可以把数据中重复的数据删去,保留唯一值。unique这个函数不仅仅对数值矩阵有效,在cell中同样起作用 5 _* [/ b9 ]" z( g. \" s0 I
C = unique(A) , X9 \ ? A4 u2 z5 s
unique还有一些拓展的语法和功能,有兴趣的朋友可以在MATLAB文档中查看,不过光这个基本功能,就已经非常够用了 / g; K( d1 V6 p
第二个要推荐的函数是排序,sort和sortrows,两种函数都有排序的功能,但是使用场景不太一样
_$ m0 |4 Y7 X; N( z t* E9 ~) t sort的功能是,将矩阵或者cell中的每行或者每列进行升序或降序排列,其中A代表待处理的矩阵或cell数据,dim的选择有1和2,分别代表对每列和每行进行排序,direction的选择有ascend或 descend,分别代表升序和降序
9 ?7 C, w4 W& g+ c7 F, n B = sort(A,dim,direction) " M. y* D# [5 F3 Z
sortrows的功能是,将矩阵或者cell根据某一列进行升序或降序排列,其中A代表待处理的矩阵或cell数据,column代表根据第几列进行排序,direction的选择有ascend或 descend,分别代表升序和降序
; [* N: a$ V0 O1 ?# S- l( I B = sortrows(A,column ,direction)
7 L4 Y* Q: H0 i 最后推荐的一个函数是tabulate,非常强的一个命令,可以实现对数据的统计分析,输出的结果有三列,分别是去重后的数据,出现的次数,已经对应的百分比 % }/ z( a; a8 j: c
再结合sortrows对tabulate生成的结果进行排序,就很容易获得各个数据根据频率进行排序的结果 - y. v" N1 C, m; K! A, D
6 q; i+ ? ~5 ^
除了上面提到的几个日常比较常用的函数,还有一些我非常推荐的函数,平时我用的不太多,但是如果用到的时候找不到会很抓狂的那种 4 a0 h |4 j3 Z j3 [) ^
比如reshape,可以根据自己的需求对数组进行重构
! P; N7 o M$ n) N; b l/ }) l isequal,可以用来确定两个数组是否相等 9 y$ }2 I3 h+ K( R, f& S
datenum,datestr相信大家比较熟悉,可以将日期转换成序列值和字符,平时在处理时间相关数据的时候,还可以考虑用years,days,hours,minutes,seconds等等来计算持续时间 & Q3 V% J: J, A! o8 O" x
常用函数这部分内容就介绍到这,其实还有很多非常赞的函数,欢迎大家把自己喜欢的函数发到评论区
3 @2 A+ P6 P: U* v- d( X: j8 W* a: W1 W; s. k
6. 数据爬取
& s2 Q: ?) F) H% z, ~ 数据爬取部分,其实我想讲的是爬虫,不过也不能算数据分析的技巧,我讲这部分内容,更多的是出于建模竞赛的原因 / a3 G: b' {; x3 }7 N4 y9 W) S( L
建模、仿真和验证,其实是需要数据的支持的。脱离实际意义的建模,靠拍脑门做出来的结果,都是不提倡的
2 l* R+ b# U' [' z 最简单的情况,如果有现成的数据文件,可以根据今天聊到的第三部分,读取数据文件之后进行分析 ) `* f9 z0 Y" e
如果没有这些数据,我推荐大家使用MATLAB读取网页的函数webread进行数据爬取 3 M9 `% J4 [) N# V6 y
data = webread(url)
$ H! U) e B% }( l- n0 v 爬取到数据之后,再通过regexp函数正则法处理网页数据
2 j) m3 E3 W5 a/ w 这部分聊的比较浅,但也很难三两句话把爬虫讲完,推荐大家一个相关的MATLAB爬虫视频,讲的是我之前用MATLAB爬取B站,视频很短,一共7分钟,大家一边看一边跟着做练习,基本上半个小时也就全整明白了(知乎不给放二维码,有需要的朋友,直接上B站搜打浦桥程序员吧)
( a' C5 Z, T3 g3 a0 b: S* ~ 7. 薅系列工具 % x& ?4 n" t8 k6 I
最后一部分要安利给大家的是,由我自己开发的薅系列工具 " t; U, l, }1 h3 o( Z6 d
目前反响最好的是薅曲线(HaoCurve),从图片中提取曲线的原始数据。之前不少参加过建模竞赛的朋友经常私信说,拿薅曲线来做结果验证特别管用 ' q0 N9 V6 J8 r' ?+ J3 F
虽然这个工具我平时用到的不太多,不过就冲8000多的下载量来说,我还是很推荐的。需要的朋友,戳下方的文章链接获取工具下载方式
* h8 G) W% ^; v$ @1 C. S 0 l% Y7 @) u1 f
3 r4 h2 H( g( F7 [0 F6 l( i1 U & c- P: f* s4 n t
5 C1 y2 {5 H& V! z/ L4 v$ @+ M8 G 我个人用的比较多的是另外两款工具,一个是薅文件(HaoFile),里面的历史代码检索功能很强大,可以大大减少找代码写脚本的时间,在数据分析过程中,很多脚本和功能都是可以复用的,有需要的朋友,戳下方的文章链接获取工具下载方式 2 A# O2 y, f$ A, r! C9 r) {# F
! P8 ^# L6 v2 C8 h- ]9 }9 w 打浦桥程序员:背几段MATLAB代码就那么难吗? # T2 h% N0 C% N ^+ C7 _! F
, u( K$ Q7 R* | f
% X- C' R/ B' f
3 K# ?3 i3 y6 J7 P6 ^
% L; t+ K+ y6 s! T# A
另一款工具是薅模版(HaoTemplate),如果最终数据分析的交付文档有格式上的要求,薅模版能就发挥它的作用,可以生成特定格式的Excel或Word模版代码,这可比自己手动去调格式方便很多,有需要的朋友,戳下方的文章链接获取工具下载方式 * u- V8 f; m2 e/ l2 Z8 ?# s
. S$ ~2 Q8 B4 x' i# k# h( j
9 D- K/ S! v% ^5 V: e. ]9 q
v8 `" U$ o! s/ z
Z7 K7 n, E' s; i& i/ k 薅系列工具还有很多,不过在数据分析这部分,我最推荐的是这三款工具
5 J+ J9 L; p/ r
) Q& U6 o# a( h* R5 k 不知觉间,写了这么多字 & j" x0 ^9 a' U J
今天总结的小技巧,未必是最适合大家的方法,但确实是我这些年养成的一些处理习惯
# @; k8 m( P7 S- Z, ], U 希望今天总结的方法,对大家平时的工作学习有所帮助,当然大家如果有更推荐的小技巧,欢迎在评论区补充
6 U# c5 z- G" Q4 W0 B' x$ u* } 如果你也对MATLAB感兴趣的话,欢迎关注我的微信公众号“打浦桥程序员”
0 b; b" ~. N8 ~- l D! O P$ [$ X, q; l5 |( S
/ T I5 }8 ?$ d% f- _3 N9 J$ |
7 y1 y5 F" r4 b* O. }$ B5 |1 n- s2 \
) }6 Y2 u' j, L O4 J0 R& a1 L' p |