罗兰关于MATLAB的艺术

将想法转化为MATLAB

在MATLAB中使用文本

我想向大家介绍今天的客座博主,Dave Bergstein, MathWorks的MATLAB产品经理。在今天的帖子中,Dave讨论了MATLAB文本处理的最新更新。

内容

在今天的帖子中,我分享了一个使用new的文本处理示例字符串数组和一系列新的文本处理功能,两者都在R2016b中引入。我也建议什么时候使用最好字符串字符,或细胞为文本,并分享一些我们对未来的想法。

也一定要看看Toshi的帖子介绍字符串数组和罗兰的文章歌颂琴弦

例子:我的公交车晚点多久?

我在纽约的朋友谈到她的公共汽车路线上的延误。让我们看一些数据,看看火车和公共汽车的典型延误情况。的开放纽约计划共享数据,包括超过15万公共交通事件跨越6年。我下载了这个数据的CSV文件从:https://data.ny.gov/Transportation/511-NY-MTA-Events-Beginning-2010/i8wu-pqzv

导入数据

将数据读入表readtable并指定TextType名称-值对的字符串将文本作为字符串数组读取。

数据= readtable (511 _ny_mta_events__beginning_2010.csv“TextType”“字符串”);
警告:变量名被修改为有效的MATLAB标识符。原始名称保存在VariableDescriptions属性中。

下面是表格中的变量列表:

data.Properties.VariableNames
ans = 1×13 cell array列1到4 'EventType' 'OrganizationName' 'FacilityName' 'Direction'列5到9 'City' ' 'County' 'State' 'CreateTime' 'CloseTime' ' column 10到13 'EventDescription' ' ' respondingorganiziz…' 'Latitude' '经度'

数据。EventDescription是包含事件描述的字符串数组。让我们仔细看看这些事件。

eventsStr = data.EventDescription;

与字符向量或字符向量的单元格数组不同,字符串数组的每个元素本身就是字符串。看看我如何索引字符串数组,就像我将一个数字数组,并取回字符串数组。

eventsStr (1:3)
ans = 3×1的字符串数组”MTA纽约过境巴士:由于早些时候洪水Q11汉密尔顿海滩恢复正常服务”“MTA纽约过境巴士:由于施工,向北M1总线的第147街领域:初级“亚当·鲍威尔“MTA纽约交通地铁:由于延迟,布朗克斯绑定# 2 & 3线内文斯街车站(布鲁克林)”

许多事件描述报告延误,如“操作晚了10分钟”。例如,查看事件5180中如何报告26分钟的延迟。

eventsStr (5180)
“MTA长岛铁路:由于轨道上的碎片,蒙托克站(萨福克县)和牙买加站(皇后区)之间西行蒙托克分支。上午6:44从蒙托克出发,定于上午9:32从牙买加出发,由于汉普顿湾附近的轨道上有一辆未经授权的车辆,延误了26分钟。”

确定延迟

我想找到所有包含' late '的事件。MATLAB R2016b还引入了十多个用于处理文本的新函数。这些函数使用字符向量、字符向量的单元格数组和字符串数组。你可以从字符和字符串页在我们的文档。

我将文本全部转换为小写字母,并确定哪些事件包含' late '包含函数。

eventsStr =低(eventsStr);idx =包含(eventsStr,“晚了”);lateEvents = eventsStr (idx);

提取延迟时间

我使用函数从像“操作10分钟迟到”这样的短语中提取迟到分钟extractAfterextractBefore

让我们看看第一个晚事件。我们要找的那个短语并没有出现在这次事件中。当我们寻找'operating'后面的文本时,我们得到a失踪字符串。

lateEvents (1) extractAfter (lateEvents (1),“操作”
mta长岛铁路:由于延误,在speakk站和纽约Penn站(曼哈顿)之间的西行巴比伦分支,上午5:08从纽约出发,上午7:02到巴比伦晚了15分钟

让我们看看第二个晚事件。这个字符串包含短语'操作14分钟晚了'。在“操作”后提取文本,我们得到“由于信号问题,晚了14分钟”。在'minutes late'之前提取文本,我们得到' 14 ',我们可以使用它转换成一个数值

lateEvents(2) s = extractAfter(lateEvents(2),“操作”) s = extractBefore(s,“分钟”) minLate = double(s)
ans = " mta长岛铁路:由于延迟西行ronkonkoma分支出的车站(萨福克县)飞机于8:01点火车由于为佩恩车站47点运行14分钟晚了由于信号问题”s =“14分钟晚了由于信号问题”=“14”minLate = 14

成功!我们从事件描述中提取了列车延误。现在让我们把这些都放在一起。我从所有事件中提取迟到的分钟数,并使用rmmissing函数。然后我将其余的值转换为数字使用并绘制出结果的直方图。

s = extractAfter (lateEvents“操作”);= extractBefore(年代,“分钟”);s = rmmissing(年代);minLate =双(s);直方图(minLate 0:5:40) ylabel (事件的数量)包含(“分钟”)标题({交通延误的“纽约大都会运输局”})

据报道,航班延误通常是10-15分钟。这个简单的程序可以捕捉到许多运输延误,但不是全部。这种模式并不总是适合(再考虑一下lateEvents (1)).我还遗漏了任何可能在数小时内报告的延误。你能改进它吗?

文本数据

字符串数组是文本数据的一个很好的选择,比如上面的例子,因为它们的内存效率更高,而且比字符向量的单元格数组(以前称为cellstr).

让我们比较一下内存使用情况。将字符串数组转换为字符向量的单元格数组cellstr命令并检查内存.参见Bytes列-它显示字符串数组的效率提高了约12%。

eventsCell = cellstr (eventsStr);谁事件*
名称大小字节类属性eventcell 151225x1 73208886 cell eventsStr 151225x1 64662486 string

对于许多较小的文本块,节省的内存要大得多。例如,假设我想将每个单词存储为一个单独的数组元素。方法将所有150,000个报告合并为一个长字符串加入函数。然后使用分裂函数。结果是一个在单独的元素中存储超过400万个单词的字符串数组。这里节省的内存接近2倍。

wordsStr =分裂(加入(eventsStr));wordsCell =分裂(加入(eventsCell));谁字*
Name Size Bytes Class Attributes wordcell 4356256x1 535429652 cell wordsStr 4356256x1 284537656 string

字符串数组的性能也更好。您可以将字符串数组与R2016b中引入的文本操作函数结合使用,从而获得最佳性能。这里我比较的是取代的字符串数组strrep字符向量的单元格数组。看看取代使用字符串数组的速度大约是4倍strrep使用单元格数组。

f1 = @() replace(eventsStr,“延迟”“晚了”);f2 = @() strrep(eventcell,)“延迟”“晚了”);时间(f1)时间(f2)
Ans = 0.062507 Ans = 0.23239

关于文本类型的建议

那么,你应该为所有的文本使用字符串数组吗?也许现在还不是时候。MATLAB有三种不同的方式存储文本:

  • 特征向量(字符
  • 字符串数组(字符串
  • 字符向量单元格数组(细胞

现在(从R2017a开始),我们鼓励您使用字符串数组来存储文本数据,比如传输事件。我们不建议在其他地方使用字符串数组,因为字符串数组在MATLAB中还没有被接受。注意我是如何使用字符向量来指定文件名的readtable以及用于图形标题的字符向量单元格数组。

展望未来

那将来呢?我们认为字符串数组比字符向量和字符向量的单元数组提供更好的体验。我们的计划是随着时间的推移扩大字符串数组的使用范围。

在接下来的几个版本中,我们将更新更多的MATLAB函数和属性,以接受字符串数组以及字符向量的单元数组。这样,在更多的地方使用字符串数组就会变得更容易。

接下来我们将用字符串数组替换MATLAB中字符向量的单元格数组。注意,单元格数组本身不会去任何地方。它们是一种重要的MATLAB容器类型,适合存储混合数据类型或大小参差不齐的数组。但我们预计它们对文本数据的使用将减少,并在很大程度上被字符串数组取代,字符串数组的内存效率更高,对纯文本数据的性能更好。

除此之外,随着时间的推移,我们将在新的函数和新的属性中使用字符串数组来代替字符向量(但是为了兼容性,我们将在许多地方继续返回字符向量)。我们希望字符向量将继续存在,以实现版本到版本的代码兼容性和特殊的用例。

说到兼容性:我们非常关心MATLAB代码的版本到版本兼容性,今天比以往任何时候都更关心。因此,我们在滚出字符串数组中采取以下步骤:

  1. 文本操作函数(旧的和新的)返回它们传递的文本类型。这意味着您可以选择使用这些函数中的字符串(没有必要使用字符串)。注意我是怎么使用的分裂加入上面的字符串数组或字符向量的单元格数组。
  2. 我们推荐字符串数组用于文本数据应用程序。这里有选择使用字符串的方法。在这个例子中,我选择从readtable使用TextType名称-值对。字符串数组是由函数返回的extractBefore因为我传递了一个字符串数组作为输入。
  3. 为了兼容,我们添加了花括号索引字符串数组,它返回字符向量。当使用花括号进行索引时,单元格数组将返回它们的内容{}.使用字符向量单元格数组的代码通常用花括号索引数组以访问字符向量。这样的代码可以处理字符串数组,因为花括号索引也将返回字符向量。看看下面的代码如何返回相同的结果f是单元格数组或字符串:
d = datetime (“现在”);f = {“h”“米”“年代”};%使用单元格数组n = 1:3, d.Format = f{n};disp (d)结束
9 43 10
f = (“h”“m”“s”];%使用字符串数组n = 1:3, d.Format = f{n};disp (d)结束
9 43 10

期待从我这里听到更多关于这个话题的内容。请在下方留言与我们分享你的想法。我们感兴趣的收到你的信

我们希望字符串数组将帮助您实现您的目标,我们正在采取的步骤将提供一个顺利的采用。如果您还没有尝试过字符串数组,请参阅我们的文档字符和字符串




发布与MATLAB®R2017a

|

评论

要留下评论,请点击在这里登录到您的MathWorks帐户或创建一个新帐户。