4.2 Index 和 Summarize

回顾之前定义的 grades_2020() 数据集:

  1. grades_2020()
namegrade_2020
Sally1.0
Bob5.0
Alice8.5
Hank4.0

可以通过 . 语法提取 DataFrame 中的 name 列向量,正如之前 Section 3struct 的操作那般:

  1. function names_grades1()
  2. df = grades_2020()
  3. df.name
  4. end
  5. names_grades1()
  1. ["Sally", "Bob", "Alice", "Hank"]

或者,可以像 Array 那样通过 Symbol 或特殊字符索引 DataFrame第二个索引是列索引

  1. function names_grades2()
  2. df = grades_2020()
  3. df[!, :name]
  4. end
  5. names_grades2()
  1. ["Sally", "Bob", "Alice", "Hank"]

注意, df.namedf[!, :name] 完全相同, 这可以自行验证:

  1. julia> df = DataFrame(id=[1]);
  2. julia> @edit df.name

这两个例子都会得到 :name。 同样,也存在 df[:, :name] 这样的语法,不过它复制了 :name 列。 大多数情况下, df[!, :name] 是最佳的做法,因为它更通用,而且没有内存拷贝,对其的所有操作都是 in-place 的。

对于任意 , 例如第二行, 可以使用 第一个索引作为行索引

  1. df = grades_2020()
  2. df[2, :]
namegrade_2020
Bob5.0

或者创建函数来获取某一行 i

  1. function grade_2020(i::Int)
  2. df = grades_2020()
  3. df[i, :]
  4. end
  5. grade_2020(2)
namegrade_2020
Bob5.0

还可以使用 切片 (与 Array 类似)来仅获取 names 列的前两行:

  1. grades_indexing(df) = df[1:2, :name]
  2. grades_indexing(grades_2020())
  1. ["Sally", "Bob"]

如果假设表中的每个名字是唯一的,那么可以编写一个函数来通过 name 获取每个人的成绩。 要实现此操作,需将上表转换为一种 Julia 基本数据结构,即可以实现映射的 Dict

  1. function grade_2020(name::String)
  2. df = grades_2020()
  3. dic = Dict(zip(df.name, df.grade_2020))
  4. dic[name]
  5. end
  6. grade_2020("Bob")
  1. 5.0

这是可行的,因为 zip 会同时遍历 df.namedf.grade_2020,就像 “拉链” 那样:

  1. df = grades_2020()
  2. collect(zip(df.name, df.grade_2020))
  1. ("Sally", 1.0)
  1. ("Bob", 5.0)
  1. ("Alice", 8.5)
  1. ("Hank", 4.0)

然而, DataFrameDict 操作仅在元素唯一的情况下可行。 一般情况下,上述条件并不成立,所以需要学习如何对 DataFrame 进行 filter 操作。

CC BY-NC-SA 4.0 Jose Storopoli, Rik Huijzer, Lazaro Alonso, 刘贵欣 (中文翻译), 田俊 (中文审校)