Skip to content

Commit 729b237

Browse files
committed
cimport is_list_like
1 parent 61ba5df commit 729b237

File tree

6 files changed

+24
-9
lines changed

6 files changed

+24
-9
lines changed

doc/source/user_guide/reshaping.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ You can join this with the original to get an expanded ``DataFrame``.
828828

829829
.. ipython:: python
830830
831-
df[['keys']]join(df['values'].explode())
831+
df[['keys']].join(df['values'].explode())
832832
833833
834834
This routine will replace empty lists with ``np.nan`` and preserve scalar entries. The dtype of the resulting ``Series`` is always ``object``.

pandas/_libs/lib.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cdef bint c_is_list_like(object, bint)

pandas/_libs/lib.pyx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ def is_period(val: object) -> bool:
887887
return util.is_period_object(val)
888888

889889

890-
cpdef is_list_like(obj: object, allow_sets: bool = True):
890+
def is_list_like(obj: object, allow_sets: bool = True):
891891
"""
892892
Check if the object is list-like.
893893
@@ -926,15 +926,19 @@ cpdef is_list_like(obj: object, allow_sets: bool = True):
926926
>>> is_list_like(np.array(2)))
927927
False
928928
"""
929+
return c_is_list_like(obj, allow_sets)
929930

931+
932+
933+
cdef inline bint c_is_list_like(object obj, bint allow_sets):
930934
return (
931935
isinstance(obj, abc.Iterable)
932936
and
933937
# we do not count strings/unicode/bytes as list-like
934938
not isinstance(obj, (str, bytes))
935939
and
936940
# exclude zero-dimensional numpy arrays, effectively scalars
937-
not (isinstance(obj, np.ndarray) and obj.ndim == 0)
941+
not (util.is_array(obj) and obj.ndim == 0)
938942
and
939943
# exclude sets if allow_sets is False
940944
not (allow_sets is False and isinstance(obj, abc.Set))

pandas/_libs/reshape.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ from cython import Py_ssize_t
44
from numpy cimport (int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t,
55
uint32_t, uint64_t, float32_t, float64_t, ndarray)
66
import numpy
7-
from pandas._libs.lib import is_list_like
7+
from pandas._libs.lib cimport c_is_list_like
88

99

1010
ctypedef fused reshape_t:
@@ -121,7 +121,7 @@ def explode(ndarray[object] values):
121121
counts = numpy.zeros(n, dtype='int64')
122122
for i in range(n):
123123
v = values[i]
124-
if is_list_like(v):
124+
if c_is_list_like(v, False):
125125
if len(v):
126126
counts[i] += len(v)
127127
else:
@@ -135,7 +135,7 @@ def explode(ndarray[object] values):
135135
for i in range(n):
136136
v = values[i]
137137

138-
if is_list_like(v):
138+
if c_is_list_like(v, False):
139139
if len(v):
140140
for j in range(len(v)):
141141
result[count] = v[j]

pandas/core/series.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
is_datetime64_dtype,
2828
is_datetimelike,
2929
is_dict_like,
30+
is_object_dtype,
3031
is_extension_array_dtype,
3132
is_extension_type,
3233
is_hashable,
@@ -3635,7 +3636,7 @@ def reorder_levels(self, order):
36353636
result.index = result.index.reorder_levels(order)
36363637
return result
36373638

3638-
def explode(self) -> 'Series':
3639+
def explode(self) -> "Series":
36393640
"""
36403641
Create new Series expanding a list-like column.
36413642
@@ -3648,7 +3649,7 @@ def explode(self) -> 'Series':
36483649
See Also
36493650
--------
36503651
Series.str.split: Split string values on specified separator.
3651-
Series.unstakc: Unstack, a.k.a. pivot, Series with MultiIndex to produce DataFrame.
3652+
Series.unstack: Unstack, a.k.a. pivot, Series with MultiIndex to produce DataFrame.
36523653
36533654
Examples
36543655
--------
@@ -3680,7 +3681,7 @@ def explode(self) -> 'Series':
36803681
Scalars will be returned unchanged.
36813682
Empty list-likes will result in a np.nan for that row.
36823683
"""
3683-
if not len(self):
3684+
if not len(self) or not is_object_dtype(self):
36843685
return self.copy()
36853686

36863687
values, counts = reshape.explode(np.asarray(self.array))

pandas/tests/series/test_explode.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import pytest
12
import numpy as np
23

34
import pandas as pd
@@ -68,6 +69,14 @@ def test_invert_array():
6869
tm.assert_series_equal(result, df["a"].rename())
6970

7071

72+
@pytest.mark.parametrize(
73+
"s", [pd.Series([1, 2, 3]), pd.Series(pd.date_range("2019", periods=3, tz="UTC"))]
74+
)
75+
def non_object_dtype(s):
76+
result = s.explode()
77+
tm.assert_series_equal(result, s)
78+
79+
7180
def test_typical_usecase():
7281

7382
df = pd.DataFrame([{"var1": "a,b,c", "var2": 1}, {"var1": "d,e,f", "var2": 2}])

0 commit comments

Comments
 (0)