导航和访问结构化数据
鉴于Nushell对结构化数据的强大支持,一些常见任务涉及导航和访问这些数据。
本节索引
- 背景和定义
- 单元格路径
- 使用
get
和select
- 示例 -
get
与select
对比(表格行) - 示例 -
select
多行多列
- 示例 -
- 使用可选操作符处理缺失数据
- 带空格的键/列名
- 其他访问结构化数据的命令
背景
对于下面的示例和描述,请记住关于结构化数据的几个定义:
- 列表: 列表包含零个或多个任意类型的值。零值的列表称为"空列表"
- 记录: 记录包含零个或多个命名键及其对应值。记录值的数据也可以是任何类型。零键值对的记录称为"空记录"
- 嵌套数据: 列表、记录或表格中包含的值可以是基本类型或结构化数据本身。这意味着数据可以多层嵌套且形式多样:
- 列表值可以包含表格、记录甚至其他列表
- 表格: 表格是记录的列表
- 记录值可以包含表格、列表和其他记录
- 这意味着表格的记录也可以包含嵌套的表格、列表和其他记录
- 列表值可以包含表格、记录甚至其他列表
提示
因为表格是记录的列表,任何适用于列表的命令或语法也适用于表格。反之则不一定成立;有些命令和语法适用于表格但不适用于列表。
单元格路径
单元格路径是访问结构化数据内部值的主要方式。这种路径基于类似于电子表格的概念,其中列有名称,行有编号。单元格路径的名称和索引用点分隔。
记录
对于记录,单元格路径指定键的名称,这是一个string
。
示例 - 访问记录值:
let my_record = {
a: 5
b: 42
}
$my_record.b + 5
# => 47
列表
对于列表,单元格路径指定列表中值的位置(索引)。这是一个int
:
示例 - 访问列表值:
记住,列表索引从0开始。
let scoobies_list = [ Velma Fred Daphne Shaggy Scooby ]
$scoobies_list.2
# => Daphne
表格
- 要访问列,单元格路径使用列名,这是一个
string
- 要访问行,它使用行的索引号,这是一个
int
- 要访问单个单元格,它使用列名和行索引的组合
接下来的几个示例将使用以下表格:
let data = [
[date temps condition ];
[2022-02-01T14:30:00+05:00, [38.24, 38.50, 37.99, 37.98, 39.10], 'sunny' ],
[2022-02-02T14:30:00+05:00, [35.24, 35.94, 34.91, 35.24, 36.65], 'sunny' ],
[2022-02-03T14:30:00+05:00, [35.17, 36.67, 34.42, 35.76, 36.52], 'cloudy' ],
[2022-02-04T14:30:00+05:00, [39.24, 40.94, 39.21, 38.99, 38.80], 'rain' ]
]
展开查看数据可视化表示
╭───┬─────────────┬───────────────┬───────────╮
│ # │ date │ temps │ condition │
├───┼─────────────┼───────────────┼───────────┤
│ 0 │ 2 years ago │ ╭───┬───────╮ │ sunny │
│ │ │ │ 0 │ 38.24 │ │ │
│ │ │ │ 1 │ 38.50 │ │ │
│ │ │ │ 2 │ 37.99 │ │ │
│ │ │ │ 3 │ 37.98 │ │ │
│ │ │ │ 4 │ 39.10 │ │ │
│ │ │ ╰───┴───────╯ │ │
│ 1 │ 2 years ago │ ╭───┬───────╮ │ sunny │
│ │ │ │ 0 │ 35.24 │ │ │
│ │ │ │ 1 │ 35.94 │ │ │
│ │ │ │ 2 │ 34.91 │ │ │
│ │ │ │ 3 │ 35.24 │ │ │
│ │ │ │ 4 │ 36.65 │ │ │
│ │ │ ╰───┴───────╯ │ │
│ 2 │ 2 years ago │ ╭───┬───────╮ │ cloudy │
│ │ │ │ 0 │ 35.17 │ │ │
│ │ │ │ 1 │ 36.67 │ │ │
│ │ │ │ 2 │ 34.42 │ │ │
│ │ │ │ 3 │ 35.76 │ │ │
│ │ │ │ 4 │ 36.52 │ │ │
│ │ │ ╰───┴───────╯ │ │
│ 3 │ 2 years ago │ ╭───┬───────╮ │ rain │
│ │ │ │ 0 │ 39.24 │ │ │
│ │ │ │ 1 │ 40.94 │ │ │
│ │ │ │ 2 │ 39.21 │ │ │
│ │ │ │ 3 │ 38.99 │ │ │
│ │ │ │ 4 │ 38.80 │ │ │
│ │ │ ╰───┴───────╯ │ │
╰───┴─────────────┴───────────────┴───────────╯
这表示天气数据形式的表格,有三列:
- date: 每天的Nushell
date
- temps: Nushell
list
,包含5个float
值,表示该地区不同气象站的温度读数 - conditions: 每天的Nushell
string
,表示该地区的天气状况
示例 - 访问表格行(记录)
访问第二天的数据作为记录:
$data.1
# => ╭───────────┬───────────────╮
# => │ date │ 2 years ago │
# => │ │ ╭───┬───────╮ │
# => │ temps │ │ 0 │ 35.24 │ │
# => │ │ │ 1 │ 35.94 │ │
# => │ │ │ 2 │ 34.91 │ │
# => │ │ │ 3 │ 35.24 │ │
# => │ │ │ 4 │ 36.65 │ │
# => │ │ ╰───┴───────╯ │
# => │ condition │ sunny │
# => ╰───────────┴───────────────╯
示例 - 访问表格列(列表)
$data.condition
# => ╭───┬────────╮
# => │ 0 │ sunny │
# => │ 1 │ sunny │
# => │ 2 │ cloudy │
# => │ 3 │ rain │
# => ╰───┴────────╯
示例 - 访问表格单元格(值)
第四天的天气状况:
$data.condition.3
# => rain
嵌套数据
由于数据可以嵌套,单元格路径可以包含对多个名称或索引的引用。
示例 - 访问嵌套表格数据
获取第三天第二个气象站的温度:
$data.temps.2.1
# => 36.67
第一个索引2
访问第三天,然后下一个索引1
访问第二个气象站的温度读数。
使用get
和select
除了上面使用的单元格路径字面量语法外,Nushell还提供了几个使用单元格路径的命令。其中最重要的是:
get
等同于使用单元格路径字面量,但支持变量名和表达式。get
与上面的单元格路径示例一样,返回单元格路径指示的值。select
有微妙但关键的区别。它返回指定的数据结构本身,而不仅仅是它的值。- 在表格上使用
select
将返回一个大小相等或更小的表格 - 在列表上使用
select
将返回一个大小相等或更小的列表 - 在记录上使用
select
将返回一个大小相等或更小的记录
- 在表格上使用
继续使用上面的示例表格:
示例 - get
与select
对比(表格行)
$data | get 1
# => ╭───────────┬───────────────╮
# => │ date │ 2 years ago │
# => │ │ ╭───┬───────╮ │
# => │ temps │ │ 0 │ 35.24 │ │
# => │ │ │ 1 │ 35.94 │ │
# => │ │ │ 2 │ 34.91 │ │
# => │ │ │ 3 │ 35.24 │ │
# => │ │ │ 4 │ 36.65 │ │
# => │ │ ╰───┴───────╯ │
# => │ condition │ sunny │
# => ╰───────────┴───────────────╯
$data | select 1
# => ╭───┬─────────────┬───────────────┬───────────╮
# => │ # │ date │ temps │ condition │
# => ├───┼─────────────┼───────────────┼───────────┤
# => │ 0 │ 2 years ago │ ╭───┬───────╮ │ sunny │
# => │ │ │ │ 0 │ 35.24 │ │ │
# => │ │ │ │ 1 │ 35.94 │ │ │
# => │ │ │ │ 2 │ 34.91 │ │ │
# => │ │ │ │ 3 │ 35.24 │ │ │
# => │ │ │ │ 4 │ 36.65 │ │ │
# => │ │ │ ╰───┴───────╯ │ │
# => ╰───┴─────────────┴───────────────┴───────────╯
注意:
示例 - select
多行多列
因为select
结果是新表格,所以可以指定多个列名、行索引,甚至两者都指定。此示例创建一个新表格,包含第一行和第二行的date和condition列:
$data | select date condition 0 1
# => ╭───┬─────────────┬───────────╮
# => │ # │ date │ condition │
# => ├───┼─────────────┼───────────┤
# => │ 0 │ 2 years ago │ sunny │
# => │ 1 │ 2 years ago │ sunny │
# => ╰───┴─────────────┴───────────╯
带空格的键/列名
如果键名或列名包含空格或其他阻止其作为裸词字符串访问的字符,则可以引用键名。
示例:
let record_example = {
"key x":12
"key y":4
}
$record_example."key x"
# => 12
# 或
$record_example | get "key x"
# => 12
当键名可能与数值混淆时,也需要引号。
示例:
let record_example = {
"1": foo
"2": baz
"3": far
}
$record_example."1"
# => foo
不要将键名与此情况下的行索引混淆。这里,第一项被分配了键名1
(字符串)。如果使用transpose
命令转换为表格,键1
(string
)将位于行索引0
(整数)。
处理缺失数据
可选操作符
默认情况下,如果无法访问请求的行或列,单元格路径访问将失败。要抑制这些错误,可以在单元格路径成员后添加?
将其标记为可选:
示例 - 可选操作符
使用上面的温度数据:
let cp: cell-path = $.temps?.1 # 仅获取temps列中第二个位置的数据
# 哎呀,我们删除了temps列
$data | reject temps | get $cp
默认情况下,通过可选操作符访问时,缺失的单元格将被替换为null
。
为缺失或null
数据设置默认值
default
命令可用于为缺失或null的列结果应用默认值。
let missing_value = [{a:1 b:2} {b:1}]
$missing_value
# => ╭───┬────┬───╮
# => │ # │ a │ b │
# => ├───┼────┼───┤
# => │ 0 │ 1 │ 2 │
# => │ 1 │ ❎ │ 1 │
# => ╰───┴────┴───╯
let with_default_value = ($missing_value | default 'n/a' a)
$with_default_value
# => ╭───┬─────┬───╮
# => │ # │ a │ b │
# => ├───┼─────┼───┤
# => │ 0 │ 1 │ 2 │
# => │ 1 │ n/a │ 1 │
# => ╰───┴─────┴───╯
$with_default_value.1.a
# => n/a