在 Julia DataFrame 中,感叹号在索引中的含义是什么?

17

我曾认为感叹号!是逻辑运算符NOT的符号。现在,学习DataFrames包中的索引时,我发现这个:data[!,:Treatment]。这似乎与使用已知的冒号符号:相同。

data[:,:Treatment]==data[!,:Treatment]true

那么为什么会有这样的冗余呢?

2个回答

16
! 在索引中是特定于 DataFrames 的,其表示您需要对存储数据的底层向量进行引用,而不是副本。您可以在此处阅读有关索引 DataFrames 的所有内容:here。在您的示例中,两者都是 ==,因为所有值都相同,但它们不是 ===,因为 df[:, :Treatment] 会给您一个底层数据的副本。
julia> using DataFrames

julia> df = DataFrame(y = [1, 2, 3]);

julia> df[:, :y] == df[!, :y] # true because all values are equal
true

julia> df[:, :y] === df[!, :y] # false because they are not the same vector
false

那么这与C语言类似的解引用运算符*是一样的吗? - user7295926
3
您可以将数据框(dataframe)看作是一个包含向量的结构体,每个向量代表一列数据。 df [!,:y]df.y 指向相同的内存块,因此它们是相同的向量。请注意,这只是大致的比喻。 - François Févotte
1
一个小注释是,df[!,:y]可以作为广播赋值的左手边,而如果在df中不存在:y(由于Base的限制),则不允许使用df.y。此外,df[!,cols]可用于创建一个新的数据框,其中包含来自df的多个列,而无需复制它们(与df [:,cols]相反,后者将重新分配所有列)。 - Bogumił Kamiński

11
引用 DataFrames.jl 的文档
列可以直接(即不需要复制)通过 df.col df [!,:col] 访问。 由于 df [!,:col] 不进行复制,因此更改此语法返回的列向量的元素将影响存储在原始 df 中的值。 要获取列的拷贝,请使用 df [:,:col] :更改此语法返回的向量不会更改 df
以下示例可能会更清晰说明此问题:
julia> using DataFrames

julia> df = DataFrame(x = rand(5), y=rand(5))
5×2 DataFrame
│ Row │ x        │ y         │
│     │ Float64Float64   │
├─────┼──────────┼───────────┤
│ 10.9378920.42232   │
│ 20.544130.932265  │
│ 30.9613720.680818  │
│ 40.9587880.923667  │
│ 50.9425180.0428454
# `a` is a copy of `df.x`: modifying it will not affect `df`
julia> a = df[:, :x]
5-element Array{Float64,1}:
 0.9378915597741728
 0.544130347207969
 0.9613717853719412
 0.958788066884128
 0.9425183324742632

julia> a[2] = 1;

julia> df
5×2 DataFrame
│ Row │ x        │ y         │
│     │ Float64Float64   │
├─────┼──────────┼───────────┤
│ 10.9378920.42232   │
│ 20.544130.932265  │
│ 30.9613720.680818  │
│ 40.9587880.923667  │
│ 50.9425180.0428454
# `b` is a view of `df.x`: any change made to it will be reflected in df
julia> b = df[!, :x]
5-element Array{Float64,1}:
 0.9378915597741728
 0.544130347207969
 0.9613717853719412
 0.958788066884128
 0.9425183324742632

julia> b[2] = 1;

julia> df
5×2 DataFrame
│ Row │ x        │ y         │
│     │ Float64Float64   │
├─────┼──────────┼───────────┤
│ 10.9378920.42232   │
│ 21.00.932265  │
│ 30.9613720.680818  │
│ 40.9587880.923667  │
│ 50.9425180.0428454

请注意,由于使用 ! 进行索引不涉及任何数据复制,因此通常更加高效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接