我曾认为感叹号!
是逻辑运算符NOT
的符号。现在,学习DataFrames
包中的索引时,我发现这个:data[!,:Treatment]
。这似乎与使用已知的冒号符号:
相同。
data[:,:Treatment]==data[!,:Treatment]
是true
。
那么为什么会有这样的冗余呢?
我曾认为感叹号!
是逻辑运算符NOT
的符号。现在,学习DataFrames
包中的索引时,我发现这个:data[!,:Treatment]
。这似乎与使用已知的冒号符号:
相同。
data[:,:Treatment]==data[!,:Treatment]
是true
。
那么为什么会有这样的冗余呢?
!
在索引中是特定于 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
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 │
│ │ Float64 │ Float64 │
├─────┼──────────┼───────────┤
│ 1 │ 0.937892 │ 0.42232 │
│ 2 │ 0.54413 │ 0.932265 │
│ 3 │ 0.961372 │ 0.680818 │
│ 4 │ 0.958788 │ 0.923667 │
│ 5 │ 0.942518 │ 0.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 │
│ │ Float64 │ Float64 │
├─────┼──────────┼───────────┤
│ 1 │ 0.937892 │ 0.42232 │
│ 2 │ 0.54413 │ 0.932265 │
│ 3 │ 0.961372 │ 0.680818 │
│ 4 │ 0.958788 │ 0.923667 │
│ 5 │ 0.942518 │ 0.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 │
│ │ Float64 │ Float64 │
├─────┼──────────┼───────────┤
│ 1 │ 0.937892 │ 0.42232 │
│ 2 │ 1.0 │ 0.932265 │
│ 3 │ 0.961372 │ 0.680818 │
│ 4 │ 0.958788 │ 0.923667 │
│ 5 │ 0.942518 │ 0.0428454 │
请注意,由于使用 !
进行索引不涉及任何数据复制,因此通常更加高效。
*
是一样的吗? - user7295926df [!,:y]
和df.y
指向相同的内存块,因此它们是相同的向量。请注意,这只是大致的比喻。 - François Févottedf[!,:y]
可以作为广播赋值的左手边,而如果在df
中不存在:y
(由于Base的限制),则不允许使用df.y
。此外,df[!,cols]
可用于创建一个新的数据框,其中包含来自df
的多个列,而无需复制它们(与df [:,cols]
相反,后者将重新分配所有列)。 - Bogumił Kamiński