Skip to content

Commit 0fac3be

Browse files
bkaminsnalimilan
authored andcommitted
improve DataFrame constructors and conversions for Vector and Matrix (#1325)
1 parent fc3f95f commit 0fac3be

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

src/dataframe/dataframe.jl

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ particularly a Vector or CategoricalVector.
88
99
```julia
1010
DataFrame(columns::Vector, names::Vector{Symbol}; makeunique::Bool=false)
11+
DataFrame(columns::Matrix, names::Vector{Symbol}; makeunique::Bool=false)
1112
DataFrame(kwargs...)
1213
DataFrame(pairs::Pair{Symbol}...; makeunique::Bool=false)
1314
DataFrame() # an empty DataFrame
@@ -20,7 +21,7 @@ DataFrame(ds::Vector{Associative})
2021
2122
**Arguments**
2223
23-
* `columns` : a Vector with each column as contents
24+
* `columns` : a Vector with each column as contents or a Matrix
2425
* `names` : the column names
2526
* `makeunique` : if `false` (the default), an error will be raised
2627
if duplicates in `names` are found; if `true`, duplicate names will be suffixed
@@ -81,7 +82,8 @@ mutable struct DataFrame <: AbstractDataFrame
8182
if length(columns) == length(colindex) == 0
8283
return new(Vector{Any}(0), Index())
8384
elseif length(columns) != length(colindex)
84-
throw(DimensionMismatch("Number of columns ($(length(columns))) and number of column names ($(length(colindex))) are not equal"))
85+
throw(DimensionMismatch("Number of columns ($(length(columns))) and number of" *
86+
" column names ($(length(colindex))) are not equal"))
8587
end
8688
lengths = [isa(col, AbstractArray) ? length(col) : 1 for col in columns]
8789
minlen, maxlen = extrema(lengths)
@@ -127,13 +129,20 @@ function DataFrame(; kwargs...)
127129
end
128130
end
129131

130-
function DataFrame(columns::AbstractVector,
131-
cnames::AbstractVector{Symbol} = gennames(length(columns));
132+
function DataFrame(columns::AbstractVector, cnames::AbstractVector{Symbol};
132133
makeunique::Bool=false)::DataFrame
134+
if !all(col -> isa(col, AbstractVector), columns)
135+
# change to throw(ArgumentError("columns argument must be a vector of AbstractVector objects"))
136+
Base.depwarn("passing columns argument with non-AbstractVector entries is deprecated", :DataFrame)
137+
end
133138
return DataFrame(convert(Vector{Any}, columns), Index(convert(Vector{Symbol}, cnames),
134139
makeunique=makeunique))
135140
end
136141

142+
DataFrame(columns::AbstractMatrix, cnames::AbstractVector{Symbol} = gennames(size(columns, 2));
143+
makeunique::Bool=false) =
144+
DataFrame(Any[columns[:, i] for i in 1:size(columns, 2)], cnames, makeunique=makeunique)
145+
137146
# Initialize an empty DataFrame with specific eltypes and names
138147
function DataFrame(column_eltypes::AbstractVector{T}, cnames::AbstractVector{Symbol},
139148
nrows::Integer; makeunique::Bool=false)::DataFrame where T<:Type
@@ -916,14 +925,7 @@ function Base.append!(df1::DataFrame, df2::AbstractDataFrame)
916925
return df1
917926
end
918927

919-
function Base.convert(::Type{DataFrame}, A::AbstractMatrix)
920-
n = size(A, 2)
921-
cols = Vector{Any}(n)
922-
for i in 1:n
923-
cols[i] = A[:, i]
924-
end
925-
return DataFrame(cols, Index(gennames(n)))
926-
end
928+
Base.convert(::Type{DataFrame}, A::AbstractMatrix) = DataFrame(A)
927929

928930
function Base.convert(::Type{DataFrame}, d::Associative)
929931
colnames = keys(d)

src/deprecated.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import Base: @deprecate
22

3+
function DataFrame(columns::AbstractVector)
4+
Base.depwarn("calling vector of vectors constructor without passing column names is deprecated", :DataFrame)
5+
DataFrame(columns, gennames(length(columns)))
6+
end
7+
38
@deprecate by(d::AbstractDataFrame, cols, s::Vector{Symbol}) aggregate(d, cols, map(eval, s))
49
@deprecate by(d::AbstractDataFrame, cols, s::Symbol) aggregate(d, cols, eval(s))
510

test/constructors.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ module TestConstructors
2828
@test df[:x1] == df2[:x1]
2929
@test df[:x2] == df2[:x2]
3030

31+
df2 = DataFrame([0.0 1.0;
32+
0.0 1.0;
33+
0.0 1.0])
34+
names!(df2, [:x1, :x2])
35+
@test df[:x1] == df2[:x1]
36+
@test df[:x2] == df2[:x2]
37+
38+
df2 = DataFrame([0.0 1.0;
39+
0.0 1.0;
40+
0.0 1.0], [:a, :b])
41+
names!(df2, [:a, :b])
42+
@test df[:x1] == df2[:a]
43+
@test df[:x2] == df2[:b]
44+
3145
@test df == DataFrame(x1 = Union{Float64, Missing}[0.0, 0.0, 0.0],
3246
x2 = Union{Float64, Missing}[1.0, 1.0, 1.0])
3347
@test df == DataFrame(x1 = Union{Float64, Missing}[0.0, 0.0, 0.0],

0 commit comments

Comments
 (0)