|
! P- M) g& m7 O8 [2 n6 A 最近一段时间,工作上花了不少时间用MATLAB处理工厂下线的数据,数据庞大不说,复杂度也高,各种推算和统计 1 ?- | s0 S/ w: D5 @1 o7 M( `2 i
所以今天我打算总结一下,平时我在用MATLAB做数据分析时常用的几个小技巧 . z9 a j+ Q) s3 B! k* @2 p; t
正好全国大学生数学建模竞赛下周就要开始了,希望今天的分享对参赛的朋友有所帮助 * v8 A \' E# X! j$ P
虽然不知道到时候会有哪些选题,但是能肯定的是,不管是什么题目,都离不开数据分析,这是唯一比赛前能好好准备的 & p% \# J8 T- E2 x( D& Z
1. 数据类型的转换
# V. t7 i" h% {( S) Y( V 有一类问题,不论你MATLAB水平如何,平时写代码的时候多少总会遇到,就是数据类型不一致,需要转换 % d2 R; e2 w3 ^6 Q; t r
至于什么是数据类型,这个问题我就不科普了,大家可以直接在MATLAB命令栏“doc 数据类型”
& B( A( R' O: I5 I" h0 g2 f6 R # A' S" N p# S2 j: s9 F
通常在数据转换这个问题上,涉及到的比较常见几种的数据类型有double,char,cell,struct
: R- G$ A* W6 X0 |9 f 我给大家准备了一张数据类型转换的关系图,用class判断一下转换前的两种数据类型,然后按照下面这张图处理就完事了 % q. J6 x" t5 O3 l0 c
9 [& u3 x; h( y" h% o8 v' r
2. 字符串的对比
1 y; t: [, ^+ Q 第二个经常需要处理的问题是,字符串的对比 % t+ h/ H; G$ f. e
这里不单单指的是字符串,还包括cell元胞里面的字符串定位 7 Y3 X: \$ u$ z5 y
如果单纯只是字符串的话,要判断两个字符串是否相同,strcmp函数可以实现对比 % \+ D" _- z1 p. b( {: f. W
strcmp(abc,abc) ! r( p3 l; N$ X* F0 Z/ ~, W
判断字符串中是否包含某种字符串,可以使用contains函数 / Z" s+ Y& M1 Q1 Y V
contains(abc,ab)
* q# L0 l, j7 L! |% Q 判断字符串中在哪几位出现某种字符串,可以使用regexp函数 / ` t2 @/ k# ] K* O( L/ l
regexp(abac,a) 0 p1 A* |9 z8 ^9 p9 M
更常碰到的场景是,在cell元胞里面判断字符串,比如维度1x1000的cell中,定位哪几个cell里面的字符串是‘abc’,还是通过strcmp实现对比,再通过find定位 " s9 p) h7 U( q: e4 h
a = strcmp(Cell_variable,abc);" p# ^# ~) f7 P5 I* z
b = find(a == 1) " z. Z0 m6 N- O0 H5 D
同样,要判断这1x1000的cell中,定位哪几个cell中的字符串,带有‘ab’,可以使用contains函数,再用find定位
& c( e- X2 v9 L; o) k; O. [2 t, G a = contains (Cell_variable,ab);
5 x8 m! ]/ D6 q$ V b = find(a == 1)
& K3 `5 I B, X7 c. @1 ]( A 掌握上面这两点,在平时处理cell的字符串,基本上就够用了
5 n! v; @+ k+ ^) O. f; s5 |) N* z 3. 文件的读取写入
( ], A1 J9 y" i. A 文件的读取写入同样非常重要,在数据分析过程中,对应着信息的获取和数据处理结果的输出 & s1 `# E- ^8 J% f
mat, txt, excel是平时最常碰到的文件类型 2 I0 Y% \ }5 B/ k1 S
mat就不用多说了,MATLAB中的一种文件类型,用于存储workspace中的变量,在数据分析过程中,可以经常把运算结果或中间阶段的数据,作为mat进行保存 $ m% k7 D% G- q( V8 A$ H \
加载mat文件,用的是“load 文件名”命令,也可以双击mat文件,保存mat文件,用的是“save 文件名”命令,也可以workspace右键保存
1 n. S; r! \3 D; ~8 V9 U txt的读取方式有非常多,网上也有各种各样的介绍,我就介绍两种最常用,也是目前我一直在用的两种方法 % e9 Z$ f5 D) P+ j
第一种是通过importdata(‘test.txt’)命令,读取的结果是一个多行一列的cell元胞,后续的数据处理也就方便了,cell里面的字符串定位处理在前面也已经介绍过
; z& s. I/ k- Q" M/ R" i 另一种方法是,通过MATLAB工具条里的“导入数据”按钮,这种方法的一个好处是,导入过程中有很多非常人性化的设置,比如数据的分隔,范围定义,数据的输出类型等等 / Y. T7 H8 n9 q# Q# l
导出的选择也有不少,可以选择直接导出到workspace,也可以选择生成脚本或者是function,方便同类型文本的重复使用,对于不太喜欢写脚本导入数据的朋友,我比较推荐这种方式 0 P( D- L" C2 w- B
0 n* o& N# |- V+ @6 t
* Z) l. F. N& X2 R' `9 h
* z9 S& q* l& M! ` txt的写入,可以通过fopen,fprintf,fclose实现,基本上我所有GUI中关于代码生成的功能,都是通过这个方式将代码写入m脚本的,给大家举一个简单的txt写入的例子代码
4 Q1 A2 I% z/ ^& d6 w; ]5 ^0 h fid = fopen(test.txt,wt);4 ]8 l. a; b5 y9 c& L" ^# O# X# T2 q
fprintf(fid,test1\n);
7 ]4 X, p- P# c; |3 M, y+ D. N fprintf(fid,test2\n);3 w9 \/ Z6 K4 _' C; V( E9 e- i- I- V
fclose(fid); ) f" m' b5 u) A2 P$ F% C1 j$ q9 y
关于txt的读取写入,我再多介绍一点,txt是文本文件中的一种,就是那种右键打开能读得懂的文件。类似的文本文件还有很多,像m文件,mdl模型文件,dcm文件,c代码等等,只要是文本文件,都可以用txt处理的方式,对目标文件进行读取写入。
' @9 W; `! r& A. P, A1 U" ~. d 最后讲一下Excel读取写入的问题,常写MATLAB脚本的朋友,对xlsread和xlswrite肯定不陌生,对应的是Excel的读取和写入
) {& S% T) t+ w S8 ? [num,txt,raw] = xlsread(filename,sheet,xlRange)
* K6 g- v1 Q" p! d; |6 q6 I) ^ xlswrite(filename,A,sheet,xlRange) 6 t( f+ }7 u8 N8 t& `; v* d
但是目前MATLAB官方已经不推荐使用这两种方式了,替代的函数是readtable和writetable $ ?6 p# Y b1 b4 E+ ]8 s( h
T = readtable(filename)2 x C" z. v2 A* L4 f
writetable(T,filename)
9 f; \! `6 }6 u' Q7 I8 `! F9 A" e
d( w0 U" W# _+ p; `9 `' y 如果数据是cell元胞的话,替代的函数是readcell和writecell 8 x3 x [" _" p, Z
T = readcell(filename)
j! N$ @" E* T4 u$ { writecell(T,filename) 9 k. M& Z8 H+ I) e4 D- a O
大家根据自己的个人习惯选择其中一种方式,两种方式在功能实现上目前并没有太大区别 4 ~! \- a) b$ N& @ ^8 ?/ N" z
4. 数据可视化 - m; ]9 |. C# j6 v7 O
数据可视化,结果的呈现,也是数据分析过程中至关重要的一环
) M0 q$ U S7 V* N 像大家非常熟悉的函数plot,就可以用来画曲线图,但是有时候仅仅曲线图并不足以来呈现结果,还需要用到比如像三维图,柱状图,饼状图,蜡烛图等等 9 G5 G, J# b/ i; n z
这部分我并不打算给大家罗列各种图形对应代码命令,大家也没必要刻意地去死记这些代码,安利一个非常通用的方法 0 t R! {% D* W6 @0 i9 S) C5 A/ Y, T4 q
在选择需要可视化的数据之后,在MATLAB工具条的绘图窗口,选取你喜欢的图形,就能生成你需要的结果图了 # k5 i" w1 ]# p, ]
! M+ K5 p. d2 y/ m0 s |+ v7 d 不过,至于图片的细节,像title,legend,网格,还是需要自己微调,但这都不是事,再安利大家一个简单的方法,完全不用上网去搜 9 S2 B* a3 B4 Y$ Q( W; q% l
在生成窗口中,点击属性检查器,然后根据自己的需要完善图片的细节,最后通过生成代码,就能看到这部分作图操作的原始代码了,大家也能在代码的基础上再微调,或者复用
0 ]7 u$ w- b, C) k) D- X
, ? x3 o, d: o6 Y' c5 t! c
4 C7 I/ V; D0 B) o4 r/ H: ` ' G9 {6 g# _* e4 {: {/ w6 F. T
5. 数据处理的常用函数
, }& W+ {8 C4 G* I3 c 关于数据处理的函数,像max,min,mean,std这些函数都是比较常用的函数,分别是最大值,最小值,平均值,标准差
* e0 I1 O: T; p5 E. }2 C! u 再安利大家几个平时我在处理数据时最常用的几个函数
- e7 a5 J' E# v8 i3 _6 h1 q 第一个是unique函数,可以把数据中重复的数据删去,保留唯一值。unique这个函数不仅仅对数值矩阵有效,在cell中同样起作用
+ l/ }4 R; |5 i C = unique(A)
/ w! I$ S, U4 w unique还有一些拓展的语法和功能,有兴趣的朋友可以在MATLAB文档中查看,不过光这个基本功能,就已经非常够用了
$ M( b, T$ B- o3 v" A 第二个要推荐的函数是排序,sort和sortrows,两种函数都有排序的功能,但是使用场景不太一样
7 L" t+ w3 Z) u5 `1 `) w sort的功能是,将矩阵或者cell中的每行或者每列进行升序或降序排列,其中A代表待处理的矩阵或cell数据,dim的选择有1和2,分别代表对每列和每行进行排序,direction的选择有ascend或 descend,分别代表升序和降序
* {/ `3 j: ^% C& L* V) i9 c+ j B = sort(A,dim,direction) 7 `( G% T4 Q8 S* v4 I
sortrows的功能是,将矩阵或者cell根据某一列进行升序或降序排列,其中A代表待处理的矩阵或cell数据,column代表根据第几列进行排序,direction的选择有ascend或 descend,分别代表升序和降序 $ @# p; ]& H# I' m5 f
B = sortrows(A,column ,direction) / J9 k4 S2 v$ F
最后推荐的一个函数是tabulate,非常强的一个命令,可以实现对数据的统计分析,输出的结果有三列,分别是去重后的数据,出现的次数,已经对应的百分比 3 b0 Y: N, a+ ~/ G! x1 G- G
再结合sortrows对tabulate生成的结果进行排序,就很容易获得各个数据根据频率进行排序的结果 6 x+ d6 G2 e2 z* W, [
5 \5 M6 T, Z$ u, l/ z- E; ^
除了上面提到的几个日常比较常用的函数,还有一些我非常推荐的函数,平时我用的不太多,但是如果用到的时候找不到会很抓狂的那种
# C% H# u, _9 j 比如reshape,可以根据自己的需求对数组进行重构 " B/ j/ Z7 B! B5 L5 `- w2 h" o
isequal,可以用来确定两个数组是否相等 1 c, t( f6 ~; }* }/ f
datenum,datestr相信大家比较熟悉,可以将日期转换成序列值和字符,平时在处理时间相关数据的时候,还可以考虑用years,days,hours,minutes,seconds等等来计算持续时间
0 O: R) V% Q7 D2 C+ e 常用函数这部分内容就介绍到这,其实还有很多非常赞的函数,欢迎大家把自己喜欢的函数发到评论区 6 _- v. H8 m0 ^
, w: Z3 N' o2 ]8 q2 i! P: o: X
6. 数据爬取 9 s! N9 o, j+ }4 A+ j
数据爬取部分,其实我想讲的是爬虫,不过也不能算数据分析的技巧,我讲这部分内容,更多的是出于建模竞赛的原因 # g) z! m6 ^ F R& E9 }; _
建模、仿真和验证,其实是需要数据的支持的。脱离实际意义的建模,靠拍脑门做出来的结果,都是不提倡的
9 p. q8 a e+ L; N* Q" O 最简单的情况,如果有现成的数据文件,可以根据今天聊到的第三部分,读取数据文件之后进行分析
- G0 p) C& D6 Q' n- O 如果没有这些数据,我推荐大家使用MATLAB读取网页的函数webread进行数据爬取 % \- V w6 |: m" a9 z5 ]
data = webread(url)
" i+ b- d5 m5 z+ n8 o 爬取到数据之后,再通过regexp函数正则法处理网页数据
/ c: u8 I q ^ 这部分聊的比较浅,但也很难三两句话把爬虫讲完,推荐大家一个相关的MATLAB爬虫视频,讲的是我之前用MATLAB爬取B站,视频很短,一共7分钟,大家一边看一边跟着做练习,基本上半个小时也就全整明白了(知乎不给放二维码,有需要的朋友,直接上B站搜打浦桥程序员吧) " k$ x; T0 Q o3 n6 B9 r
7. 薅系列工具
! a E$ D' D0 z: l; v1 g 最后一部分要安利给大家的是,由我自己开发的薅系列工具
( q6 g. d! h2 ]: [) _9 ?4 Q0 g 目前反响最好的是薅曲线(HaoCurve),从图片中提取曲线的原始数据。之前不少参加过建模竞赛的朋友经常私信说,拿薅曲线来做结果验证特别管用
- d: r5 i( E' G+ a8 E6 w( s 虽然这个工具我平时用到的不太多,不过就冲8000多的下载量来说,我还是很推荐的。需要的朋友,戳下方的文章链接获取工具下载方式 & |. x; P$ _/ \
" h+ \: l5 g' ]0 E& @
8 e: {$ Q8 C5 A* a( h5 O: l9 n ( M$ r5 J R4 H1 {, F
9 W0 G( {: B) g4 ~ 我个人用的比较多的是另外两款工具,一个是薅文件(HaoFile),里面的历史代码检索功能很强大,可以大大减少找代码写脚本的时间,在数据分析过程中,很多脚本和功能都是可以复用的,有需要的朋友,戳下方的文章链接获取工具下载方式 ) s- k/ ^( O* ~' U9 D3 @
: M* c/ Z8 c, V/ F G; ?; n 打浦桥程序员:背几段MATLAB代码就那么难吗? 6 r" _! Q; B) v$ M6 m; ?$ ^6 o* q
" l1 |9 N: F" {" |3 P/ Y" p
+ `0 V; G; k% V8 ]
+ B u1 z1 L) J$ ], ]: S& W
& h% t$ q; @* M; c 另一款工具是薅模版(HaoTemplate),如果最终数据分析的交付文档有格式上的要求,薅模版能就发挥它的作用,可以生成特定格式的Excel或Word模版代码,这可比自己手动去调格式方便很多,有需要的朋友,戳下方的文章链接获取工具下载方式 # _( B& E @" s, \
. ^7 y z1 J1 ?* V) B
* {: [ P" Z. ?, E% s
& n. c5 O7 b( w/ `7 I
9 u }/ W: k ]7 T 薅系列工具还有很多,不过在数据分析这部分,我最推荐的是这三款工具
4 w( i+ o% ?6 l, A( G
7 I# z" N- L( V U0 N 不知觉间,写了这么多字
4 E$ E# K7 I. {$ U$ n! n 今天总结的小技巧,未必是最适合大家的方法,但确实是我这些年养成的一些处理习惯 + l4 n2 E. Q( g7 i' o
希望今天总结的方法,对大家平时的工作学习有所帮助,当然大家如果有更推荐的小技巧,欢迎在评论区补充
, O5 A* }" K% |7 _ 如果你也对MATLAB感兴趣的话,欢迎关注我的微信公众号“打浦桥程序员”
- p6 M1 s7 Q5 l. _& a1 r- Q3 z: f' {, |% t, P$ ]
& j' Y" s9 S! R* k1 D a J( B# p2 V6 ?" ^) C
/ @: G2 t- B v6 G
|