Skip to content

Commit 9aab379

Browse files
merge with upstream
2 parents 643eb44 + 35b0d1d commit 9aab379

File tree

9 files changed

+78
-22
lines changed

9 files changed

+78
-22
lines changed

doc/source/conf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@
114114
):
115115
exclude_patterns.append(rel_fname)
116116
elif single_doc and rel_fname != pattern:
117+
if "\\" in rel_fname:
118+
rel_fname = rel_fname.replace("\\", "/")
117119
exclude_patterns.append(rel_fname)
118120

119121
with open(os.path.join(source_path, "index.rst.template"), encoding="utf-8") as f:

doc/source/development/community.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ people who are hesitant to bring up their questions or ideas on a large public
114114
mailing list or GitHub.
115115

116116
If this sounds like the right place for you, you are welcome to join using
117-
`this link <https://join.slack.com/t/pandas-dev-community/shared_invite/zt-2blg6u9k3-K6_XvMRDZWeH7Id274UeIg>`_!
117+
`this link <https://join.slack.com/t/pandas-dev-community/shared_invite/zt-3813u5fme-hmp5izpbeFl9G8~smrkE~A>`_!
118118
Please remember to follow our `Code of Conduct <https://pandas.pydata.org/community/coc.html>`_,
119119
and be aware that our admins are monitoring for irrelevant messages and will remove folks who use
120120
our

doc/source/user_guide/enhancingperf.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ We have a :class:`DataFrame` to which we want to apply a function row-wise.
5050
{
5151
"a": np.random.randn(1000),
5252
"b": np.random.randn(1000),
53-
"N": np.random.randint(100, 1000, (1000)),
53+
"N": np.random.randint(100, 1000, (1000), dtype="int64"),
5454
"x": "x",
5555
}
5656
)
@@ -83,7 +83,7 @@ using the `prun ipython magic function <https://ipython.readthedocs.io/en/stable
8383
.. ipython:: python
8484
8585
# most time consuming 4 calls
86-
%prun -l 4 df.apply(lambda x: integrate_f(x["a"], x["b"], x["N"]), axis=1) # noqa E999
86+
%prun -l 4 df.apply(lambda x: integrate_f(x['a'], x['b'], x['N']), axis=1)
8787
8888
By far the majority of time is spend inside either ``integrate_f`` or ``f``,
8989
hence we'll concentrate our efforts cythonizing these two functions.
@@ -164,7 +164,7 @@ can be improved by passing an ``np.ndarray``.
164164

165165
.. ipython:: python
166166
167-
%prun -l 4 df.apply(lambda x: integrate_f_typed(x["a"], x["b"], x["N"]), axis=1)
167+
%prun -l 4 df.apply(lambda x: integrate_f_typed(x['a'], x['b'], x['N']), axis=1)
168168
169169
.. ipython::
170170

@@ -204,7 +204,7 @@ calls are needed to utilize this function.
204204

205205
.. ipython:: python
206206
207-
%timeit apply_integrate_f(df["a"].to_numpy(), df["b"].to_numpy(), df["N"].to_numpy())
207+
%timeit apply_integrate_f(df['a'].to_numpy(), df['b'].to_numpy(), df['N'].to_numpy())
208208
209209
Performance has improved from the prior implementation by almost ten times.
210210

@@ -218,7 +218,7 @@ and ``wraparound`` checks can yield more performance.
218218

219219
.. ipython:: python
220220
221-
%prun -l 4 apply_integrate_f(df["a"].to_numpy(), df["b"].to_numpy(), df["N"].to_numpy())
221+
%prun -l 4 apply_integrate_f(df['a'].to_numpy(), df['b'].to_numpy(), df['N'].to_numpy())
222222
223223
.. ipython::
224224

@@ -253,7 +253,7 @@ and ``wraparound`` checks can yield more performance.
253253

254254
.. ipython:: python
255255
256-
%timeit apply_integrate_f_wrap(df["a"].to_numpy(), df["b"].to_numpy(), df["N"].to_numpy())
256+
%timeit apply_integrate_f_wrap(df['a'].to_numpy(), df['b'].to_numpy(), df['N'].to_numpy())
257257
258258
However, a loop indexer ``i`` accessing an invalid location in an array would cause a segfault because memory access isn't checked.
259259
For more about ``boundscheck`` and ``wraparound``, see the Cython docs on

doc/source/whatsnew/v2.3.1.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Fixed regressions
2626

2727
Bug fixes
2828
~~~~~~~~~
29-
-
29+
- Fixed bug in :meth:`DataFrame.explode` and :meth:`Series.explode` where methods would fail with ``dtype="str"`` (:issue:`61623`)
3030

3131
.. ---------------------------------------------------------------------------
3232
.. _whatsnew_231.other:

pandas/core/arrays/arrow/array.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,9 +1935,9 @@ def _explode(self):
19351935
"""
19361936
# child class explode method supports only list types; return
19371937
# default implementation for non list types.
1938-
if not (
1939-
pa.types.is_list(self.dtype.pyarrow_dtype)
1940-
or pa.types.is_large_list(self.dtype.pyarrow_dtype)
1938+
if not hasattr(self.dtype, "pyarrow_dtype") or (
1939+
not pa.types.is_list(self.dtype.pyarrow_dtype)
1940+
and not pa.types.is_large_list(self.dtype.pyarrow_dtype)
19411941
):
19421942
return super()._explode()
19431943
values = self

pandas/io/formats/excel.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -303,13 +303,13 @@ def _border_style(
303303
# 'slantDashDot'
304304
# 'thick'
305305
# 'thin'
306-
if width is None and style is None and color is None:
307-
# Return None will remove "border" from style dictionary
308-
return None
309-
310306
if width is None and style is None:
311-
# Return "none" will keep "border" in style dictionary
312-
return "none"
307+
if color is None:
308+
# Return None will remove "border" from style dictionary
309+
return None
310+
else:
311+
# Return "none" will keep "border" in style dictionary
312+
return "none"
313313

314314
if style in ("none", "hidden"):
315315
return "none"
@@ -411,11 +411,6 @@ def _get_decoration(self, props: Mapping[str, str]) -> Sequence[str]:
411411
else:
412412
return ()
413413

414-
def _get_underline(self, decoration: Sequence[str]) -> str | None:
415-
if "underline" in decoration:
416-
return "single"
417-
return None
418-
419414
def _get_shadow(self, props: Mapping[str, str]) -> bool | None:
420415
if "text-shadow" in props:
421416
return bool(re.search("^[^#(]*[1-9]", props["text-shadow"]))

pandas/tests/frame/methods/test_explode.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,11 @@ def test_multi_columns_nan_empty():
297297
index=[0, 0, 1, 2, 3, 3],
298298
)
299299
tm.assert_frame_equal(result, expected)
300+
301+
302+
def test_str_dtype():
303+
# https://github.com/pandas-dev/pandas/pull/61623
304+
df = pd.DataFrame({"a": ["x", "y"]}, dtype="str")
305+
result = df.explode(column="a")
306+
assert result is not df
307+
tm.assert_frame_equal(result, df)

pandas/tests/io/formats/test_to_excel.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@
156156
"border-top-style: solid; border-top-width: 4pt",
157157
{"border": {"top": {"style": "thick"}}},
158158
),
159+
(
160+
"border-top-style: solid; border-top-width: none",
161+
{"border": {"top": {"style": "none"}}},
162+
),
163+
(
164+
"border-top-style: solid; border-top-width: 0.000001pt",
165+
{"border": {"top": {"style": "none"}}},
166+
),
159167
(
160168
"border-top-style: dotted",
161169
{"border": {"top": {"style": "mediumDashDotDot"}}},
@@ -194,6 +202,10 @@
194202
"border-top-color: blue",
195203
{"border": {"top": {"color": "0000FF", "style": "none"}}},
196204
),
205+
(
206+
"border-top-style: slantDashDot; border-top-color: blue",
207+
{"border": {"top": {"style": "slantDashDot", "color": "0000FF"}}},
208+
),
197209
# ALIGNMENT
198210
# - horizontal
199211
("text-align: center", {"alignment": {"horizontal": "center"}}),
@@ -249,6 +261,20 @@ def test_css_to_excel_multiple():
249261
} == actual
250262

251263

264+
@pytest.mark.parametrize(
265+
"css",
266+
[
267+
"border-top-style: unhandled-border-style",
268+
"border-style: another-unhandled-style",
269+
],
270+
)
271+
def test_css_to_excel_unhandled_border_style_warns(css):
272+
"""Test that unhandled border styles raise a CSSWarning."""
273+
convert = CSSToExcelConverter()
274+
with tm.assert_produces_warning(CSSWarning, match="Unhandled border style format"):
275+
convert(css)
276+
277+
252278
@pytest.mark.parametrize(
253279
"css,inherited,expected",
254280
[
@@ -330,6 +356,23 @@ def test_css_to_excel_bad_colors(input_color):
330356
assert expected == convert(css)
331357

332358

359+
@pytest.mark.parametrize("input_color", ["#", "#1234567"])
360+
def test_css_to_excel_invalid_color_raises(input_color):
361+
"""Test that invalid colors raise a ValueError."""
362+
css = (
363+
f"border-top-color: {input_color}; "
364+
f"border-right-color: {input_color}; "
365+
f"border-bottom-color: {input_color}; "
366+
f"border-left-color: {input_color}; "
367+
f"background-color: {input_color}; "
368+
f"color: {input_color}"
369+
)
370+
371+
convert = CSSToExcelConverter()
372+
with pytest.raises(ValueError, match=f"Unexpected color {input_color}"):
373+
convert(css)
374+
375+
333376
def tests_css_named_colors_valid():
334377
upper_hexs = set(map(str.upper, string.hexdigits))
335378
for color in CSSToExcelConverter.NAMED_COLORS.values():

pandas/tests/series/methods/test_explode.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,11 @@ def test_explode_pyarrow_non_list_type(ignore_index):
175175
result = ser.explode(ignore_index=ignore_index)
176176
expected = pd.Series([1, 2, 3], dtype="int64[pyarrow]", index=[0, 1, 2])
177177
tm.assert_series_equal(result, expected)
178+
179+
180+
def test_str_dtype():
181+
# https://github.com/pandas-dev/pandas/pull/61623
182+
ser = pd.Series(["x", "y"], dtype="str")
183+
result = ser.explode()
184+
assert result is not ser
185+
tm.assert_series_equal(result, ser)

0 commit comments

Comments
 (0)