罗兰对MATLAB的艺术

将想法转化为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名称-值对as字符串将文本作为字符串数组读取。

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

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

data.Properties.VariableNames
ans = 1×13单元格数组第1至4列'EventType' 'OrganizationName' 'FacilityName' 'Direction'第5至9列'City' 'County' 'State' 'CreateTime' 'CloseTime'第10至13列'EventDescription' ' respondingorganiziz…' 'Latitude' 'Longitude'

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

eventsStr = data.EventDescription;

与字符向量或字符向量的单元数组不同,字符串数组的每个元素本身都是字符串。看看我如何索引字符串数组,就像索引数字数组一样,然后返回字符串数组。

eventsStr (1:3)
ans = 3×1字符串数组"MTA NYC Transit Bus:由于之前的洪水Q11进入汉密尔顿海滩正常服务恢复" "MTA NYC Transit Bus:由于施工,147街M1北行巴士区域:Adam Clayton Powell Junior" "MTA NYC Transit Subway:由于延误,布朗克斯方向# 2和3线在内文斯街站(布鲁克林)"

许多事件描述报告了诸如“延迟10分钟”之类的延迟。例如,请查看事件5180中如何报告26分钟的延迟。

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

确定延迟

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

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

eventsStr = lower(eventsStr);idx = contains(eventsStr,“迟到”);lateEvents = eventsStr(idx);

提取延迟时间

我使用函数从“营业晚了10分钟”这样的短语中提取迟到的分钟数extractAfterextractBefore

让我们来看看第一个迟到的事件。我们正在寻找的确切短语并没有出现在这个事件中。当我们查找“operating”后面的文本时,我们得到a失踪字符串。

lateEvents (1) extractAfter (lateEvents (1),“操作”
mta长岛铁路:由于延误,从斯皮克站(斯皮克)到纽约宾夕法尼亚站(曼哈顿)之间的西行巴比伦分支,早上5:08发车,早上7:02,晚了15分钟@巴比伦

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

lateEvents(2) = extractAfter(lateEvents(2))“操作”) s = extractBefore(s,“分钟”) minLate = double(s)
mta长岛铁路:由于延误从bethpage站(suffolk县)出发的ronkonkoma西行支线上午8:01分的列车由于信号问题将于8:47分驶进penn站,由于信号问题将延误14分钟

成功!我们从事件描述中提取了火车延误。现在让我们把这些放在一起。从所有事件中提取迟到的分钟数,并删除丢失的值rmmissing函数。然后将剩下的值转换为数字,使用然后画出结果的直方图。

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

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

文本即数据

字符串数组对于上面的例子这样的文本数据来说是一个很好的选择,因为它们具有内存效率,并且比字符向量的单元格数组(以前称为cellstr)。

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

eventsCell = cellstr(eventsStr);谁事件*
eventsCell 151225x1 73208886 cell eventsStr 151225x1 64662486 string

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

wordstr = split(join(eventsStr));wordsCell = split(join(eventsCell));谁字*
名称大小字节类属性wordcell 4356256x1 535429652 cell wordstr 4356256x1 284537656 string

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

f1 = @()替换(eventsStr,“延迟”“晚了”);f2 = @() strrep(eventsCell,“延迟”“晚了”);时间(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发布


评论

要发表评论,请点击此处2017-07-29 13:313:00