回顾之前定义的 grades_2020()
数据集:
grades_2020()
name | grade_2020 |
---|---|
Sally | 1.0 |
Bob | 5.0 |
Alice | 8.5 |
Hank | 4.0 |
可以通过 .
语法提取 DataFrame
中的 name
列向量,正如之前 Section 3 中 struct
的操作那般:
function names_grades1()
df = grades_2020()
df.name
end
names_grades1()
["Sally", "Bob", "Alice", "Hank"]
或者,可以像 Array
那样通过 Symbol
或特殊字符索引 DataFrame
。 第二个索引是列索引:
function names_grades2()
df = grades_2020()
df[!, :name]
end
names_grades2()
["Sally", "Bob", "Alice", "Hank"]
注意, df.name
与 df[!, :name]
完全相同, 这可以自行验证:
julia> df = DataFrame(id=[1]);
julia> @edit df.name
这两个例子都会得到 :name
。 同样,也存在 df[:, :name]
这样的语法,不过它复制了 :name
列。 大多数情况下, df[!, :name]
是最佳的做法,因为它更通用,而且没有内存拷贝,对其的所有操作都是 in-place 的。
对于任意 行, 例如第二行, 可以使用 第一个索引作为行索引:
df = grades_2020()
df[2, :]
name | grade_2020 |
---|---|
Bob | 5.0 |
或者创建函数来获取某一行 i
:
function grade_2020(i::Int)
df = grades_2020()
df[i, :]
end
grade_2020(2)
name | grade_2020 |
---|---|
Bob | 5.0 |
还可以使用 切片 (与 Array
类似)来仅获取 names
列的前两行:
grades_indexing(df) = df[1:2, :name]
grades_indexing(grades_2020())
["Sally", "Bob"]
如果假设表中的每个名字是唯一的,那么可以编写一个函数来通过 name
获取每个人的成绩。 要实现此操作,需将上表转换为一种 Julia 基本数据结构,即可以实现映射的 Dict
:
function grade_2020(name::String)
df = grades_2020()
dic = Dict(zip(df.name, df.grade_2020))
dic[name]
end
grade_2020("Bob")
5.0
这是可行的,因为 zip
会同时遍历 df.name
和 df.grade_2020
,就像 “拉链” 那样:
df = grades_2020()
collect(zip(df.name, df.grade_2020))
("Sally", 1.0)
("Bob", 5.0)
("Alice", 8.5)
("Hank", 4.0)
然而, DataFrame
转 Dict
操作仅在元素唯一的情况下可行。 一般情况下,上述条件并不成立,所以需要学习如何对 DataFrame
进行 filter
操作。