# Difference between df\[:, :a\] and df\[!, :a\]

**URL:** <https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561>\
**Category:** General Usage\
**Tags:** dataframes\
**Created:** [September 9, 2019, 1:59pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561 "2019-09-09T13:59:36Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [September 9, 2019, 1:59pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561/1 "2019-09-09T13:59:36Z")

</div>

I recently updated my DataFrames.jl package and noticed the following deprecation warning when doing `df[:a]`:

```julia
Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.

```

I understand that I need to start doing the above as `df[:, :a]` or `df[!, :a]` but is there a difference between these? If not, what’s the purpose of having the two different syntaxes?

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [September 9, 2019, 2:01pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561/2 "2019-09-09T14:01:42Z")

</div>

First make a copy, second is a view, no?

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [September 9, 2019, 2:04pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561/3 "2019-09-09T14:04:04Z")

</div>

That sounds like it’s probably right, but I don’t know how to check 🙂

I _think_ this _might_ show that you are right:

```julia
using DataFrames

df = DataFrame([collect(1:10), collect(11:20)], [:a, :b])

julia> df[:, :a] === df[:, :a]
false

julia> df[!, :a] === df[!, :a]
true

```

In the first case, it returns false because separate copies are made while in the second case, it returns true because it’s simply referring to the same column in the same data frame…??

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [September 9, 2019, 2:13pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561/4 "2019-09-09T14:13:47Z")

</div>

Indeed. You can also use `@time` and look for allocations.

```julia
julia> @time df[:, :x1];
  0.000004 seconds (5 allocations: 256 bytes)

julia> @time df[!, :x1];
  0.000003 seconds (4 allocations: 160 bytes)

```

or use BenchmarkTools:

```julia
julia> using BenchmarkTools

julia> @btime df[:, :x1];
  57.682 ns (1 allocation: 96 bytes)

julia> @btime df[!, :x1];
  28.213 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![BeastyBlacksmith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/beastyblacksmith/32/4741_2.png) [@BeastyBlacksmith](https://discourse.julialang.org/u/BeastyBlacksmith)\
**Post date:** [September 9, 2019, 2:17pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561/5 "2019-09-09T14:17:38Z")

</div>

It is also explained [here](https://juliadata.github.io/DataFrames.jl/stable/lib/indexing/)

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [September 9, 2019, 2:36pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561/6 "2019-09-09T14:36:08Z")

</div>

I didn’t even realize that you can just do `df.a` 😆 That’s so much nicer than `df[!, :a]`

---

<div class="post-metadata">

**Author:** ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)\
**Post date:** [September 9, 2019, 3:18pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561/7 "2019-09-09T15:18:39Z")

</div>

Note, this works for everything _except_ assigning a single value to a non-existent column. That is:

```julia
julia> df = DataFrame(a=rand(10));

julia> df.b = rand(10);

julia> df.c = ["blah" for _ in 1:10];

julia> df.c .= "foo";

julia> df.d .= "bar";
ERROR: ArgumentError: column name :d not found in the data frame; existing most similar names are: :a, :b and :c
Stacktrace:
 [1] getindex(::DataFrame, ::typeof(!), ::Symbol) at /Users/ksb/.julia/packages/DataFrames/XuYBH/src/other/index.jl:241
 [2] getproperty(::DataFrame, ::Symbol) at /Users/ksb/.julia/packages/DataFrames/XuYBH/src/abstractdataframe/abstractdataframe.jl:219
 [3] top-level scope at REPL[6]:1

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 18, 2023, 9:26pm UTC](https://discourse.julialang.org/t/difference-between-df-a-and-df-a/28561/8 "2023-01-18T21:26:46Z")

</div>

2 posts were split to a new topic: [Copy vs view of DataFrame column?](https://discourse.julialang.org/t/copy-vs-view-of-dataframe-column/93182)
