How to| 整理从网站导入的数据

Wolfram 语言的连接和数字处理能力使得在网站上导入和分析数据变得理想. 在大多数情况下,这是相对简单的. 但是,不是所有网站都以易于访问的形式公布数据,正如下面显示的例子一样. 尽管如此,Wolfram 语言仅在短短的几步里完成这一工作.

美国人口普查局维护中美贸易平衡数据. 他们的 网站 显示了从1985到2009年的月度数据.

从查看可以从网站导入的部分列表开始,这些列表在 Wolfram 语言中可作为元素引用:

导入 "Data" 元素. 为了实现这个例子的目的,因为导入了大量数据,使用一个分号(;)来防止输出. 计算不带有 ;Import 命令将显示所有导入的数据:

使用 Short 来查看部分数据:

大部分输出被阻止,但是用户可以看到感兴趣的数据包含在四个元素 MonthExportsImportsBalance 组成的列表里. 因此,用户可以通过提取仅包含四个元素的列表,来获取所有数据. 为了确保只得到数据,提取所有四元素列表,其中最后一个元素是一个数值.

使用带有列表中四个下划线字符的 Cases 来提取仅有四个元素的列表. 下划线字符是可以用来代表任何 Wolfram 语言表达式的一个模式对象. 对最后一个下划线字符添加 ?NumericQ 确保用户只获取第四个和最后一个元素是数值的列表. 使用 作为 Cases 的最后一个参数指定嵌套列表 tmp 的所有层将用来搜索模式:

再次,使用 Short 来查看部分数据:

输出始于1985年12月,并且运行至1992年3月,所有有些数据还没有被返回. 具有混合格式的数据表是这样的问题的常见原因.

在这种情况下,数字表示为几个项组成的字符串,这使得它们被要求每个列表的第四个元素为数值的模式忽略:

用户可以使用 NumberString 来测试一个字符串是否包含数字,但是用户必须首先从字符串删除任何逗号.

首先,生成一个使用 StringQ 的函数来测试该变量是否是一个字符串,并且如果它是,使用 StringReplace 把逗号用空格替换. 如果该变量不是一个字符串,它不改变地返回:

生成另一个函数来测试该变量是否是一个字符串,并且如果它是,使用带有 StringMatchQNumberString 来测试该字符串是否包含数字. 如果该变量不是一个字符串,函数使用 NumericQ 来测试它是否是一个数字. 换句话说,函数将返回 True 是否它的变量包含一个数字,不管它是否是一个字符串:

用户可以在条件测试中使用应用于模式的 g[x] (符号 /;Condition 的简写形式):

查看缩短的数据,用户可以看现在它扩展到从1985年到2009年. 额外的模式匹配起作用,并且所有数据已经被提取. 请注意,在这个阶段逗号还没有被从输出删除;它们仅在条件测试的申请中被删除:

接下来,创建一个使用 ToExpression 的函数来把任何数字字符串转换成可以解释为 Wolfram 语言的输入表达式. 该函数也把字符串中任意逗号替换为一个空格:

下一个函数将测试每个列表中的第一个元素是否是一个表示年度总和的字符串,或者是否是一个表示一个日期的字符串. 如果它是一个日期,它将被转化为一个 DateList

现在使用上面的 Cases 表达式,并且增加一个应用于每个列表数据的四个元素中的每个的替换规则. 基于 g[x] 条件返回 True 的元素使用 h[x] 替换,并且因此从数字字符串转化为数字表达式. 每个列表中的第一个元素使用 j[x] 替换,它把任意日期字符串转化为DateList

查看缩短的数据,用户可以看到前面表示为字符串的日期现在被表示为 DateList. 另外注意,在任何数字中也没有逗号:

下一步,使用带有模式作为第二个变量的 DeleteCases 来从数据中删除年度总和. 对于模式,在一个列表中使用带有两个下划线字符的 "TOTAL" 来匹配任何以 "TOTAL" 为起始的列表,并且包含任何由一个或多个 Wolfram 语言表达式组成的序列:

现在没有年度总和了:

注意,数据不是正确排序的. 由于网站表格的构造方法,每个年块按照时间顺序的反顺序排列.

使用 Sort 来修改它:

现在,数据按照正确的时间顺序排列:

最后,可以绘制数据.

定义一些可以增强图形外观的选项:

为图形定义一个标签:

使用 DateListPlot 绘制基于日期的数据:

精确的数据处理步骤将取决于数据如何结构化对不同的网站不同.