Skip to content

Commit 261d443

Browse files
author
Christopher Doris
committed
no-copy conversion
1 parent b3c7b64 commit 261d443

File tree

4 files changed

+27
-15
lines changed

4 files changed

+27
-15
lines changed

src/concrete/numpy.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function init_numpy()
3939
rule = pyconvert_rule_numpysimplevalue{T, false}()
4040
saferule = pyconvert_rule_numpysimplevalue{T, true}()
4141

42-
pyconvert_add_rule(name, T, saferule, PYCONVERT_PRIORITY_CANONICAL)
42+
pyconvert_add_rule(name, T, saferule, PYCONVERT_PRIORITY_ARRAY)
4343
isuint && pyconvert_add_rule(name, UInt, sizeof(T) sizeof(UInt) ? saferule : rule)
4444
isuint && pyconvert_add_rule(name, Int, sizeof(T) < sizeof(Int) ? saferule : rule)
4545
isint && !isuint && pyconvert_add_rule(name, Int, sizeof(T) sizeof(Int) ? saferule : rule)

src/convert.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,10 @@ function init_pyconvert()
479479
pyconvert_add_rule("<arrayinterface>", AbstractArray, pyconvert_rule_array, priority)
480480
pyconvert_add_rule("<array>", AbstractArray, pyconvert_rule_array, priority)
481481
pyconvert_add_rule("<buffer>", AbstractArray, pyconvert_rule_array, priority)
482+
# more sequence types
483+
pyconvert_add_rule("pandas.core.series:Series", PyList, pyconvert_rule_sequence)
484+
pyconvert_add_rule("pandas.core.indexes.base:Index", PyList, pyconvert_rule_sequence)
485+
pyconvert_add_rule("pandas.core.arrays.base:ExtensionArray", PyList, pyconvert_rule_sequence)
482486

483487
priority = PYCONVERT_PRIORITY_FALLBACK
484488
pyconvert_add_rule("builtins:object", Py, pyconvert_rule_object, priority)

src/pywrap/PyArray.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct PyArray{T,N,M,L,R} <: AbstractArray{T,N}
2626
py::Py # underlying python object
2727
handle::Py # the data in this array is valid as long as this handle is alive
2828
function PyArray{T,N,M,L,R}(::Val{:new}, ptr::Ptr{R}, size::NTuple{N,Int}, strides::NTuple{N,Int}, py::Py, handle::Py) where {T,N,M,L,R}
29-
T isa DataType || error("T must be a DataType")
29+
T isa Type || error("T must be a Type")
3030
N isa Int || error("N must be an Int")
3131
M isa Bool || error("M must be a Bool")
3232
L isa Bool || error("L must be a Bool")

src/pywrap/PyPandasDataFrame.jl

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ function _columns(df, columnnames, columntypes)
5555
pycolumns = Py[]
5656
if df.indexname !== nothing
5757
push!(colnames, df.indexname)
58-
push!(pycolumns, df.py.index)
58+
push!(pycolumns, df.py.index.values)
5959
end
6060
for pycolname in df.py.columns
6161
colname = columnnames(pycolname)::Symbol
62-
pycolumn = df.py[pycolname]
62+
pycolumn = df.py[pycolname].values
6363
push!(colnames, colname)
6464
push!(pycolumns, pycolumn)
6565
end
@@ -78,20 +78,28 @@ function _columns(df, columnnames, columntypes)
7878
for (colname, pycolumn) in zip(colnames, pycolumns)
7979
coltype = columntypes(colname)::Union{Nothing,Type}
8080
if coltype !== nothing
81-
column = pyconvert_and_del(AbstractVector{coltype}, pycolumn)
81+
column = pyconvert(AbstractVector{coltype}, pycolumn)
8282
else
83-
column = pyconvert_and_del(AbstractVector, pycolumn)
84-
# narrow the type
85-
column = identity.(column)
86-
# convert any Py to something more useful
87-
if Py <: eltype(column)
88-
column = [x isa Py ? pyconvert(Any, x) : x for x in column]
89-
end
90-
# convert NaN to missing
91-
if eltype(column) != Float64 && Float64 <: eltype(column)
92-
column = [x isa Float64 && isnan(x) ? missing : x for x in column]
83+
column = pyconvert(AbstractVector, pycolumn)
84+
@show colname typeof(column)
85+
if eltype(column) == Py
86+
# guess a column type based on the types of the elements
87+
ts = pybuiltins.set(pybuiltins.map(pybuiltins.type, pycolumn))
88+
Ts = Type[pyconvert_preferred_type(t) for t in ts]
89+
T = isempty(Ts) ? Any : reduce(promote_type, Ts)
90+
column = pyconvert(AbstractVector{T}, pycolumn)
91+
@show ts Ts T typeof(column)
92+
# if all items are either NaN or not Float64, convert NaN to missing
93+
if T != Float64 && Float64 in Ts && !any(x isa Float64 && !isnan(x) for x in column)
94+
Ts = Type[T for T in Ts if T != Float64]
95+
push!(Ts, Missing)
96+
T = reduce(promote_type, Ts)
97+
column = pyconvert(AbstractVector{T}, pycolumn)
98+
@show Ts T typeof(column)
99+
end
93100
end
94101
end
102+
pydel!(pycolumn)
95103
push!(columns, column)
96104
push!(coltypes, eltype(column))
97105
end

0 commit comments

Comments
 (0)