45.1 数据集
词汇表
| 表达式 | 说明 |
|---|---|
Dataset[data] |
创建数据集(Dataset) |
Normal[dataset] |
将数据集转换为普通列表和关联 |
数据集
在大型组织中,计算通常围绕处理大量结构化数据展开。
Wolfram 语言提供了强大的结构化数据处理方式,称为数据集 (Dataset)。
创建数据集
一个简单的数据集示例由关联 的关联 构成。(参考关联)
创建一个可视为 2 行 3 列 的简单数据集:
wl
In[]:=data = Dataset[<|"a" -> <|"x" -> 1, "y" -> 2, "z" -> 3|>,
"b" -> <|"x" -> 5, "y" -> 10, "z" -> 7|>|>]

数据集切片
Wolfram 语言通常以表格形式显示数据集。
可以像操作关联那样提取数据集的部分。
提取元素
获取"行 b列 z的元素:
wl
In[]:=data["b", "z"]
Out[]=7
也可以先提取整个b 行,然后从结果中取z元素:
wl
In[]:=data["b"]["z"]
Out[]=7
提取行
也可以只获取数据集的整个b 行。
结果是一个新的数据集,在此处为便于阅读而显示为一列。
从原始数据集中生成b 行的新数据集:
wl
In[]:=data["b"]

下面是对应于所有z列的数据集。
生成包含所有行z列的数据集:
wl
In[]:=data[All, "z"]

函数应用
提取数据集部分只是开始。
凡是可以请求部分的位置,也可以提供一个函数,该函数将应用于该层级的所有部分。
行应用
通过对所有行的所有列应用 Total 来获取每行的总和:
wl
In[]:=data[All, Total]

抽象应用
如果用 f 替代 Total,我们可以看到发生了什么:函数被应用到每个"行"关联上。
将函数 f 应用于每一行:
wl
In[]:=data[All, f]

纯函数应用
应用一个将每个关联的 x 和 z 元素相加的函数:
wl
In[]:=data[All, #x + #z &]

其他应用
可以使用任何函数;例如 PieChart:
wl
In[9]:=data[All, PieChart]

列应用
也可以给出一个应用于所有行的函数。
抽象
此操作首先提取每个z 列的值,然后将 f 应用于结果的关联:
wl
In[]:=data[f, "z"]
Out[]=f[<|"a" -> 3, "b" -> 7|>]
列汇总
将 f 应用于所有列的总和:
wl
In[]:=data[f, Total]
Out[]=f[<|"a" -> 6, "b" -> 22|>]
其他应用
找到这些总和的最大值:
wl
In[]:=data[Max, Total]
Out[]=22
链操作
可以"链"查询,例如先计算所有行的总和,然后取出b 行的结果。
先找出所有行的总和,然后取出b 行的总和:
wl
In[]:=data[All, Total]["b"]
Out[]=22
等价于:
wl
In[14]:=data["b", Total]
Out[14]=22
运算符形式
筛选
当处理大型数据集时,常常需要根据条件选择部分。
Select 的运算符形式提供了便利的写法。
回顾
从列表中选择大于 5 的数:
wl
In[]:=Select[{1, 3, 6, 8, 2, 5, 9, 7}, # > 5 &]
Out[]={6, 8, 9, 7}
使用 Select 的运算符形式获取相同答案的另一种方法:
wl
In[]:=Select[# > 5 &][{1, 3, 6, 8, 2, 5, 9, 7}]
Out[]={6, 8, 9, 7}
数据集筛选
Select 的运算符形式是一个可以应用以实际执行 Select 操作的函数。
通过选择z 列大于 5 的行来创建数据集:
wl
In[]:=data[Select[#z > 5 &]]

对每行选择值大于 5 的列,留下不规则结构:
wl
In[18]:=data[All, Select[# > 5 &]]

转换为普通表达式
Normal将数据集转换为普通的关联 的关联:
wl
In[]:=Normal[%]
Out[19]=<|"a" -> <||>, "b" -> <|"y" -> 10, "z" -> 7|>|>
其他函数运算符形式
回顾
许多 Wolfram 语言函数都有运算符形式。
根据应用于每个元素的函数值排序:
wl
In[]:=SortBy[{1, 3, 6, 8, 2, 5, 9, 7}, If[EvenQ[#], #, 10 + #] &]
Out[]={2, 6, 8, 1, 3, 5, 7, 9}
排序
SortBy 有运算符形式:
wl
In[]:=SortBy[If[EvenQ[#], #, 10 + #] &][{1, 3, 6, 8, 2, 5, 9, 7}]
Out[]={2, 6, 8, 1, 3, 5, 7, 9}
根据 x 列和 y 列之差的值对行排序:
wl
In[]:=data[SortBy[#x - #y &]]

先对行排序,再求所有列的总和:
wl
In[]:=data[SortBy[#x - #y &], Total]

元素应用
有时你想对数据集中的每个元素应用函数。
抽象应用
对数据集中的每个元素应用 f:
wl
In[]:=data[All, All, f]

链式应用
在求元素平方和之前先对行排序:
wl
In[]:=data[SortBy[#x - #y &], Total, #^2 &]

混合数据形式
数据集可以包含列表和关联的任意混合。
下面是一个可以被视为带命名字段记录列表的数据集。
关联列表
由关联列表构成的数据集:
wl
In[]:=Dataset[{<|"x" -> 2, "y" -> 4, "z" -> 6|>, <|"x" -> 11, "y" -> 7, "z" -> 1|>}]

条目可以缺失:
wl
In[27]:=Dataset[{<|"x" -> 2, "y" -> 4, "z" -> 6|>, <|"x" -> 11, "y" -> 7|>}]
