|
! D0 Z" ^5 g/ d7 {+ {9 W$ x 最近一段时间,工作上花了不少时间用MATLAB处理工厂下线的数据,数据庞大不说,复杂度也高,各种推算和统计
5 O" W1 _# D N0 ?$ f 所以今天我打算总结一下,平时我在用MATLAB做数据分析时常用的几个小技巧 . ]/ q- R8 r$ r" F
正好全国大学生数学建模竞赛下周就要开始了,希望今天的分享对参赛的朋友有所帮助
( W# E+ S, d- T. w; i. Z 虽然不知道到时候会有哪些选题,但是能肯定的是,不管是什么题目,都离不开数据分析,这是唯一比赛前能好好准备的 . ~/ k6 F0 a' t! ~: `
1. 数据类型的转换 3 X+ ~; _8 o; D" }. t; x6 f3 L. D
有一类问题,不论你MATLAB水平如何,平时写代码的时候多少总会遇到,就是数据类型不一致,需要转换
! \" G1 i$ {2 M5 k% a. _! m. W 至于什么是数据类型,这个问题我就不科普了,大家可以直接在MATLAB命令栏“doc 数据类型”
6 T# `- c8 ?% B: F
( `, n! o- @7 a 通常在数据转换这个问题上,涉及到的比较常见几种的数据类型有double,char,cell,struct / W: i- }& _* E
我给大家准备了一张数据类型转换的关系图,用class判断一下转换前的两种数据类型,然后按照下面这张图处理就完事了
3 z2 w1 y, q0 I 0 z8 \0 ]+ d0 P4 h% d: D! }
2. 字符串的对比
% Y0 I# S4 w8 h6 k' c: N4 |. w 第二个经常需要处理的问题是,字符串的对比
3 S- P$ {7 x$ ~0 t 这里不单单指的是字符串,还包括cell元胞里面的字符串定位
' g2 H5 l+ x4 t/ S7 X 如果单纯只是字符串的话,要判断两个字符串是否相同,strcmp函数可以实现对比
6 H+ R- n0 |6 n) P strcmp(abc,abc) 0 M2 X3 H/ n9 [
判断字符串中是否包含某种字符串,可以使用contains函数 ' _* F! K: c' T3 B, V: O5 M9 U
contains(abc,ab) * R7 q: `, T E# v5 X& R! _) v$ Z
判断字符串中在哪几位出现某种字符串,可以使用regexp函数
2 T. m% X) t) | regexp(abac,a) 3 F# j- `1 c+ C/ O; g5 ^# ?
更常碰到的场景是,在cell元胞里面判断字符串,比如维度1x1000的cell中,定位哪几个cell里面的字符串是‘abc’,还是通过strcmp实现对比,再通过find定位
`' [, h, B: J# V a = strcmp(Cell_variable,abc);' B& [- R( r, W. c. W3 E/ y7 D
b = find(a == 1)
/ s# u! v8 `% z6 t 同样,要判断这1x1000的cell中,定位哪几个cell中的字符串,带有‘ab’,可以使用contains函数,再用find定位
3 ~5 i9 J/ r& h ^9 y6 P3 x; f+ a a = contains (Cell_variable,ab);% M7 M, p) X6 S
b = find(a == 1) 7 A& L4 }# O: ~7 V% j
掌握上面这两点,在平时处理cell的字符串,基本上就够用了 5 d L% X& w9 b2 |& u) \
3. 文件的读取写入 % n' K+ ]# G& X( ^6 K' U
文件的读取写入同样非常重要,在数据分析过程中,对应着信息的获取和数据处理结果的输出 6 W) D) g0 R7 ?' V# ]. ^! G; ~ N' j
mat, txt, excel是平时最常碰到的文件类型 5 M$ T1 j: I: A @1 c# a3 c6 X
mat就不用多说了,MATLAB中的一种文件类型,用于存储workspace中的变量,在数据分析过程中,可以经常把运算结果或中间阶段的数据,作为mat进行保存
/ E. e+ Q. A2 }4 m% v& A' u 加载mat文件,用的是“load 文件名”命令,也可以双击mat文件,保存mat文件,用的是“save 文件名”命令,也可以workspace右键保存
' {. \" Z5 h* z9 ?8 R. [ txt的读取方式有非常多,网上也有各种各样的介绍,我就介绍两种最常用,也是目前我一直在用的两种方法
/ R* Z" i5 h% w# M5 C, V9 e$ J5 r" O 第一种是通过importdata(‘test.txt’)命令,读取的结果是一个多行一列的cell元胞,后续的数据处理也就方便了,cell里面的字符串定位处理在前面也已经介绍过 + V9 k( j7 d, c% e& M- c" b
另一种方法是,通过MATLAB工具条里的“导入数据”按钮,这种方法的一个好处是,导入过程中有很多非常人性化的设置,比如数据的分隔,范围定义,数据的输出类型等等
( ]' T3 q. _5 R 导出的选择也有不少,可以选择直接导出到workspace,也可以选择生成脚本或者是function,方便同类型文本的重复使用,对于不太喜欢写脚本导入数据的朋友,我比较推荐这种方式
; g# O; u3 }6 Y- V6 s . C; N# h) i' ~3 z6 V, S
" V9 u' X1 @1 w' |( k
+ c( W: z. r7 x( U
txt的写入,可以通过fopen,fprintf,fclose实现,基本上我所有GUI中关于代码生成的功能,都是通过这个方式将代码写入m脚本的,给大家举一个简单的txt写入的例子代码
- Q, F4 H4 y' u. | fid = fopen(test.txt,wt);) b) p9 _3 `6 C8 }) q
fprintf(fid,test1\n);
" I( P+ A* u. h: K! A P fprintf(fid,test2\n);% ]7 E+ A4 i1 ]
fclose(fid); 7 {# z* v0 {4 g H
关于txt的读取写入,我再多介绍一点,txt是文本文件中的一种,就是那种右键打开能读得懂的文件。类似的文本文件还有很多,像m文件,mdl模型文件,dcm文件,c代码等等,只要是文本文件,都可以用txt处理的方式,对目标文件进行读取写入。 * h3 V7 O" \; u2 h8 t) A4 \! Q
最后讲一下Excel读取写入的问题,常写MATLAB脚本的朋友,对xlsread和xlswrite肯定不陌生,对应的是Excel的读取和写入
/ i: D, M1 X) n [num,txt,raw] = xlsread(filename,sheet,xlRange)
) M, J3 W. a* }+ D% @2 s0 O xlswrite(filename,A,sheet,xlRange) ( Y T* Q4 J6 [- \ `- W9 \
但是目前MATLAB官方已经不推荐使用这两种方式了,替代的函数是readtable和writetable
0 J# Y* I' B# S: ? T = readtable(filename)& S" a D6 J* Q, [+ v
writetable(T,filename)
0 ~' ?5 \8 ~; V& F* R 9 l3 M2 M- F- g2 |
如果数据是cell元胞的话,替代的函数是readcell和writecell
3 m, ?7 O3 f7 z* [3 }& I6 x$ E+ u# l T = readcell(filename); O: \4 h4 ]$ T* m& K+ h
writecell(T,filename)
5 X) E1 h5 p8 [4 Y. x9 `& J 大家根据自己的个人习惯选择其中一种方式,两种方式在功能实现上目前并没有太大区别 / H2 n8 a) A" }9 }
4. 数据可视化
0 a8 E( h/ K5 I# q1 } f6 _% l& ^9 n 数据可视化,结果的呈现,也是数据分析过程中至关重要的一环 / Q7 {7 O# c6 u/ H( R
像大家非常熟悉的函数plot,就可以用来画曲线图,但是有时候仅仅曲线图并不足以来呈现结果,还需要用到比如像三维图,柱状图,饼状图,蜡烛图等等
+ `7 G; [5 p) P$ E. l$ y4 X+ r 这部分我并不打算给大家罗列各种图形对应代码命令,大家也没必要刻意地去死记这些代码,安利一个非常通用的方法 $ m0 A6 w# u7 l
在选择需要可视化的数据之后,在MATLAB工具条的绘图窗口,选取你喜欢的图形,就能生成你需要的结果图了 - E- T- _' C& D/ @1 E, I
- m; c7 ~" f# W# y 不过,至于图片的细节,像title,legend,网格,还是需要自己微调,但这都不是事,再安利大家一个简单的方法,完全不用上网去搜 6 q6 A$ I2 P& t: k ~+ u; B
在生成窗口中,点击属性检查器,然后根据自己的需要完善图片的细节,最后通过生成代码,就能看到这部分作图操作的原始代码了,大家也能在代码的基础上再微调,或者复用 2 I1 O y c, ^4 ?. s8 e
3 r* o Z3 ]3 m; D( q3 y) |
5 G- I- T! F0 y" j- b J/ v
* c }/ _$ ]. N9 Q 5. 数据处理的常用函数
, V) A9 `" O, V0 E/ V 关于数据处理的函数,像max,min,mean,std这些函数都是比较常用的函数,分别是最大值,最小值,平均值,标准差
4 F* F; Q5 \- A 再安利大家几个平时我在处理数据时最常用的几个函数 3 l0 @7 V! m# U' ~0 j* t
第一个是unique函数,可以把数据中重复的数据删去,保留唯一值。unique这个函数不仅仅对数值矩阵有效,在cell中同样起作用 5 i: I+ f, m+ K. F' J
C = unique(A)
# A# E5 @$ H- P5 Z c unique还有一些拓展的语法和功能,有兴趣的朋友可以在MATLAB文档中查看,不过光这个基本功能,就已经非常够用了
6 u: J* u+ r6 b$ q# P0 X4 u6 e2 ` 第二个要推荐的函数是排序,sort和sortrows,两种函数都有排序的功能,但是使用场景不太一样
1 X7 f4 e N3 y" m) G$ s1 q sort的功能是,将矩阵或者cell中的每行或者每列进行升序或降序排列,其中A代表待处理的矩阵或cell数据,dim的选择有1和2,分别代表对每列和每行进行排序,direction的选择有ascend或 descend,分别代表升序和降序
$ p1 Y {. I! g8 \# q; R. u B = sort(A,dim,direction) h V$ J+ m |
sortrows的功能是,将矩阵或者cell根据某一列进行升序或降序排列,其中A代表待处理的矩阵或cell数据,column代表根据第几列进行排序,direction的选择有ascend或 descend,分别代表升序和降序
^$ U- j3 ]$ U$ T3 M4 M5 Q B = sortrows(A,column ,direction) , `0 F$ S! T" j; N; G; M- S, f
最后推荐的一个函数是tabulate,非常强的一个命令,可以实现对数据的统计分析,输出的结果有三列,分别是去重后的数据,出现的次数,已经对应的百分比 % P8 b5 J8 v5 @" Z( G( `3 @
再结合sortrows对tabulate生成的结果进行排序,就很容易获得各个数据根据频率进行排序的结果 , N3 L/ @/ t3 {, s$ b
$ y3 P3 p/ V1 o, G/ T 除了上面提到的几个日常比较常用的函数,还有一些我非常推荐的函数,平时我用的不太多,但是如果用到的时候找不到会很抓狂的那种 $ u! @5 |( I- H& W' _8 \$ W0 h9 u
比如reshape,可以根据自己的需求对数组进行重构
6 a+ g( n7 D) K( x; E$ [2 _) N/ S; `% ` isequal,可以用来确定两个数组是否相等
. m& J& x" e* {3 [# \ datenum,datestr相信大家比较熟悉,可以将日期转换成序列值和字符,平时在处理时间相关数据的时候,还可以考虑用years,days,hours,minutes,seconds等等来计算持续时间
3 H1 Q1 A8 I3 {6 g- d8 U& x8 Q 常用函数这部分内容就介绍到这,其实还有很多非常赞的函数,欢迎大家把自己喜欢的函数发到评论区
2 D6 R/ H m& W' W( O+ M7 S! N( d9 _/ c; k4 p9 d8 J' S1 b; g$ t" h- A
6. 数据爬取
3 _. D2 V. f; N! ^9 B 数据爬取部分,其实我想讲的是爬虫,不过也不能算数据分析的技巧,我讲这部分内容,更多的是出于建模竞赛的原因
+ _) F9 J! Y w: i& {2 K 建模、仿真和验证,其实是需要数据的支持的。脱离实际意义的建模,靠拍脑门做出来的结果,都是不提倡的
/ O3 A5 o& X% X! ] w 最简单的情况,如果有现成的数据文件,可以根据今天聊到的第三部分,读取数据文件之后进行分析 4 e. h+ y4 w( O8 ~! t6 ^
如果没有这些数据,我推荐大家使用MATLAB读取网页的函数webread进行数据爬取
" y: q8 @6 \, g: I$ z! m ] data = webread(url) ! j! x$ k" \: j0 {4 A
爬取到数据之后,再通过regexp函数正则法处理网页数据 , u9 K$ e: z) _: A/ r% u
这部分聊的比较浅,但也很难三两句话把爬虫讲完,推荐大家一个相关的MATLAB爬虫视频,讲的是我之前用MATLAB爬取B站,视频很短,一共7分钟,大家一边看一边跟着做练习,基本上半个小时也就全整明白了(知乎不给放二维码,有需要的朋友,直接上B站搜打浦桥程序员吧)
4 w1 z9 z, j P 7. 薅系列工具
% t5 X6 A- q. q. _/ m 最后一部分要安利给大家的是,由我自己开发的薅系列工具
+ w( |+ F1 \1 E& H F& e1 ^ 目前反响最好的是薅曲线(HaoCurve),从图片中提取曲线的原始数据。之前不少参加过建模竞赛的朋友经常私信说,拿薅曲线来做结果验证特别管用
" Q; C- ?& Q5 x& l( h3 k# y 虽然这个工具我平时用到的不太多,不过就冲8000多的下载量来说,我还是很推荐的。需要的朋友,戳下方的文章链接获取工具下载方式
' b q- s: C$ w
# i: z- Z! P4 X4 p 2 {5 P2 s: d$ j4 b* r5 P
) F% k7 N/ m% E9 }6 @( G! J
9 h7 {; \5 x; q! c2 _3 ] 我个人用的比较多的是另外两款工具,一个是薅文件(HaoFile),里面的历史代码检索功能很强大,可以大大减少找代码写脚本的时间,在数据分析过程中,很多脚本和功能都是可以复用的,有需要的朋友,戳下方的文章链接获取工具下载方式 - a1 Z0 n$ [9 i4 f( ?# a2 |
0 c+ ]. A: J- d) w8 x. `
打浦桥程序员:背几段MATLAB代码就那么难吗?
: D1 t. n H/ V$ r" N% c8 a 4 K. ~% L; }+ X1 u
( n5 D6 W9 w& I/ `2 k0 T
# Y+ T7 S* d5 ~* y5 p2 y
& b, g# [1 {5 A( a, o( ?/ a3 G 另一款工具是薅模版(HaoTemplate),如果最终数据分析的交付文档有格式上的要求,薅模版能就发挥它的作用,可以生成特定格式的Excel或Word模版代码,这可比自己手动去调格式方便很多,有需要的朋友,戳下方的文章链接获取工具下载方式 p+ G( {! ], H* i& `2 i- z0 n
9 E; T- s+ I& l% U7 s- [ , y% ~4 M& [. A/ o7 }% o
, ?/ f: C3 l. c1 V" _' E0 h+ c+ g
) l2 B% s+ C( V! A/ {" E' h 薅系列工具还有很多,不过在数据分析这部分,我最推荐的是这三款工具
: E5 Z! J7 W1 k. F6 T
2 v z+ T. c, C- ] 不知觉间,写了这么多字
7 A/ k% b1 B0 |" C 今天总结的小技巧,未必是最适合大家的方法,但确实是我这些年养成的一些处理习惯 0 ~# Z/ j8 |7 F5 }% @
希望今天总结的方法,对大家平时的工作学习有所帮助,当然大家如果有更推荐的小技巧,欢迎在评论区补充
, W3 D: V8 U* p+ Y7 _/ G 如果你也对MATLAB感兴趣的话,欢迎关注我的微信公众号“打浦桥程序员”
$ v. x: q) Q6 x$ \4 r6 Z" Q4 [" Y/ C$ c! G3 ~7 {$ o7 m4 y! |
5 u+ g% A0 ^ ?) k1 Q! Q) a' t8 ?% Y8 d" _6 e8 L, h7 K2 R% Z
0 t7 W: f5 J0 f4 z) i |