Skip to content

Commit 4514636

Browse files
authored
PERF/REF: Construct series faster in numba apply (#56048)
1 parent 1969079 commit 4514636

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

Diff for: pandas/core/_numba/extensions.py

+22-13
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
from pandas.core.indexes.base import Index
3939
from pandas.core.indexing import _iLocIndexer
40+
from pandas.core.internals import SingleBlockManager
4041
from pandas.core.series import Series
4142

4243

@@ -387,32 +388,40 @@ def box_series(typ, val, c):
387388
Convert a native series structure to a Series object.
388389
"""
389390
series = cgutils.create_struct_proxy(typ)(c.context, c.builder, value=val)
390-
class_obj = c.pyapi.unserialize(c.pyapi.serialize_object(Series))
391+
series_const_obj = c.pyapi.unserialize(c.pyapi.serialize_object(Series._from_mgr))
392+
mgr_const_obj = c.pyapi.unserialize(
393+
c.pyapi.serialize_object(SingleBlockManager.from_array)
394+
)
391395
index_obj = c.box(typ.index, series.index)
392396
array_obj = c.box(typ.as_array, series.values)
393397
name_obj = c.box(typ.namety, series.name)
394-
true_obj = c.pyapi.unserialize(c.pyapi.serialize_object(True))
395-
# This is equivalent of
396-
# pd.Series(data=array_obj, index=index_obj, dtype=None,
397-
# name=name_obj, copy=None, fastpath=True)
398-
series_obj = c.pyapi.call_function_objargs(
399-
class_obj,
398+
# This is basically equivalent of
399+
# pd.Series(data=array_obj, index=index_obj)
400+
# To improve perf, we will construct the Series from a manager
401+
# object to avoid checks.
402+
# We'll also set the name attribute manually to avoid validation
403+
mgr_obj = c.pyapi.call_function_objargs(
404+
mgr_const_obj,
400405
(
401406
array_obj,
402407
index_obj,
403-
c.pyapi.borrow_none(),
404-
name_obj,
405-
c.pyapi.borrow_none(),
406-
true_obj,
407408
),
408409
)
410+
mgr_axes_obj = c.pyapi.object_getattr_string(mgr_obj, "axes")
411+
# Series._constructor_from_mgr(mgr, axes)
412+
series_obj = c.pyapi.call_function_objargs(
413+
series_const_obj, (mgr_obj, mgr_axes_obj)
414+
)
415+
c.pyapi.object_setattr_string(series_obj, "_name", name_obj)
409416

410417
# Decrefs
411-
c.pyapi.decref(class_obj)
418+
c.pyapi.decref(series_const_obj)
419+
c.pyapi.decref(mgr_axes_obj)
420+
c.pyapi.decref(mgr_obj)
421+
c.pyapi.decref(mgr_const_obj)
412422
c.pyapi.decref(index_obj)
413423
c.pyapi.decref(array_obj)
414424
c.pyapi.decref(name_obj)
415-
c.pyapi.decref(true_obj)
416425

417426
return series_obj
418427

0 commit comments

Comments
 (0)