Skip to content

Commit f4a530f

Browse files
authored
Merge pull request #246 from pandas-dev/master
Sync Fork from Upstream Repo
2 parents ec2cce8 + 1269bc6 commit f4a530f

File tree

18 files changed

+102
-51
lines changed

18 files changed

+102
-51
lines changed

doc/source/whatsnew/v1.3.2.rst

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Fixed regressions
1919
- Regression in :meth:`DataFrame.from_records` with empty records (:issue:`42456`)
2020
- Fixed regression in :meth:`DataFrame.shift` where TypeError occurred when shifting DataFrame created by concatenation of slices and fills with values (:issue:`42719`)
2121
- Regression in :meth:`DataFrame.agg` when the ``func`` argument returned lists and ``axis=1`` (:issue:`42727`)
22+
- Fixed regression where :meth:`pandas.read_csv` raised a ``ValueError`` when parameters ``names`` and ``prefix`` were both set to None (:issue:`42387`)
23+
- Fixed regression in comparisons between :class:`Timestamp` object and ``datetime64`` objects outside the implementation bounds for nanosecond ``datetime64`` (:issue:`42794`)
2224
-
2325

2426
.. ---------------------------------------------------------------------------

pandas/_libs/tslibs/timestamps.pyx

+2-2
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,9 @@ cdef class _Timestamp(ABCTimestamp):
270270
if op == Py_EQ:
271271
return False
272272
if op == Py_LE or op == Py_LT:
273-
return other.year <= self.year
273+
return self.year <= other.year
274274
if op == Py_GE or op == Py_GT:
275-
return other.year >= self.year
275+
return self.year >= other.year
276276

277277
cdef bint _can_compare(self, datetime other):
278278
if self.tzinfo is not None:

pandas/core/construction.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,7 @@ def extract_array(
405405
For an ndarray-backed Series / Index a PandasArray is returned.
406406
407407
>>> extract_array(pd.Series([1, 2, 3]))
408-
<PandasArray>
409-
[1, 2, 3]
410-
Length: 3, dtype: int64
408+
array([1, 2, 3])
411409
412410
To extract all the way down to the ndarray, pass ``extract_numpy=True``.
413411

pandas/core/frame.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -4754,7 +4754,8 @@ def drop(
47544754
Parameters
47554755
----------
47564756
labels : single label or list-like
4757-
Index or column labels to drop.
4757+
Index or column labels to drop. A tuple will be used as a single
4758+
label and not treated as a list-like.
47584759
axis : {0 or 'index', 1 or 'columns'}, default 0
47594760
Whether to drop labels from the index (0 or 'index') or
47604761
columns (1 or 'columns').
@@ -4845,6 +4846,17 @@ def drop(
48454846
weight 1.0 0.8
48464847
length 0.3 0.2
48474848
4849+
>>> df.drop(index=('falcon', 'weight'))
4850+
big small
4851+
lama speed 45.0 30.0
4852+
weight 200.0 100.0
4853+
length 1.5 1.0
4854+
cow speed 30.0 20.0
4855+
weight 250.0 150.0
4856+
length 1.5 0.8
4857+
falcon speed 320.0 250.0
4858+
length 0.3 0.2
4859+
48484860
>>> df.drop(index='cow', columns='small')
48494861
big
48504862
lama speed 45.0

pandas/core/indexes/base.py

+3
Original file line numberDiff line numberDiff line change
@@ -5406,6 +5406,9 @@ def _get_indexer_strict(self, key, axis_name: str_t) -> tuple[Index, np.ndarray]
54065406
self._raise_if_missing(keyarr, indexer, axis_name)
54075407

54085408
keyarr = self.take(indexer)
5409+
if isinstance(key, Index):
5410+
# GH 42790 - Preserve name from an Index
5411+
keyarr.name = key.name
54095412
if keyarr.dtype.kind in ["m", "M"]:
54105413
# DTI/TDI.take can infer a freq in some cases when we dont want one
54115414
if isinstance(key, list) or (

pandas/core/reshape/tile.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import (
55
Any,
66
Callable,
7+
Literal,
78
)
89

910
import numpy as np
@@ -417,12 +418,8 @@ def _bins_to_cuts(
417418
else:
418419
bins = unique_bins
419420

420-
side = "left" if right else "right"
421-
# error: No overload variant of "searchsorted" of "ndarray" matches
422-
# argument types "Any", "str"
423-
ids = ensure_platform_int(
424-
bins.searchsorted(x, side=side) # type: ignore[call-overload]
425-
)
421+
side: Literal["left", "right"] = "left" if right else "right"
422+
ids = ensure_platform_int(bins.searchsorted(x, side=side))
426423

427424
if include_lowest:
428425
ids[np.asarray(x) == bins[0]] = 1

pandas/io/parsers/readers.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,12 @@ def _refine_defaults_read(
13021302
if delimiter and (sep is not lib.no_default):
13031303
raise ValueError("Specified a sep and a delimiter; you can only specify one.")
13041304

1305-
if names is not lib.no_default and prefix is not lib.no_default:
1305+
if (
1306+
names is not None
1307+
and names is not lib.no_default
1308+
and prefix is not None
1309+
and prefix is not lib.no_default
1310+
):
13061311
raise ValueError("Specified named and prefix; you can only specify one.")
13071312

13081313
kwds["names"] = None if names is lib.no_default else names

pandas/plotting/_matplotlib/tools.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,12 @@ def handle_shared_axes(
417417
except IndexError:
418418
# if gridspec is used, ax.rowNum and ax.colNum may different
419419
# from layout shape. in this case, use last_row logic
420+
if compat.mpl_ge_3_4_0():
421+
is_last_row = lambda x: x.get_subplotspec().is_last_row()
422+
else:
423+
is_last_row = lambda x: x.is_last_row()
420424
for ax in axarr:
421-
if ax.is_last_row():
425+
if is_last_row(ax):
422426
continue
423427
if sharex or _has_externally_shared_axis(ax, "x"):
424428
_remove_labels_from_axis(ax.xaxis)

pandas/tests/indexing/test_loc.py

+12
Original file line numberDiff line numberDiff line change
@@ -2432,6 +2432,18 @@ def test_loc_getitem_listlike_of_datetimelike_keys(self, to_period):
24322432
with pytest.raises(KeyError, match="not in index"):
24332433
ser.loc[keys]
24342434

2435+
def test_loc_named_index(self):
2436+
# GH 42790
2437+
df = DataFrame(
2438+
[[1, 2], [4, 5], [7, 8]],
2439+
index=["cobra", "viper", "sidewinder"],
2440+
columns=["max_speed", "shield"],
2441+
)
2442+
expected = df.iloc[:2]
2443+
expected.index.name = "foo"
2444+
result = df.loc[Index(["cobra", "viper"], name="foo")]
2445+
tm.assert_frame_equal(result, expected)
2446+
24352447

24362448
@pytest.mark.parametrize(
24372449
"columns, column_key, expected_columns",

pandas/tests/io/parser/common/test_common_basic.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -764,15 +764,24 @@ def test_read_table_delim_whitespace_non_default_sep(all_parsers, delimiter):
764764

765765

766766
@pytest.mark.parametrize("func", ["read_csv", "read_table"])
767-
@pytest.mark.parametrize("prefix", [None, "x"])
768-
@pytest.mark.parametrize("names", [None, ["a"]])
769-
def test_names_and_prefix_not_lib_no_default(all_parsers, names, prefix, func):
767+
def test_names_and_prefix_not_None_raises(all_parsers, func):
770768
# GH#39123
771769
f = StringIO("a,b\n1,2")
772770
parser = all_parsers
773771
msg = "Specified named and prefix; you can only specify one."
774772
with pytest.raises(ValueError, match=msg):
775-
getattr(parser, func)(f, names=names, prefix=prefix)
773+
getattr(parser, func)(f, names=["a", "b"], prefix="x")
774+
775+
776+
@pytest.mark.parametrize("func", ["read_csv", "read_table"])
777+
@pytest.mark.parametrize("prefix, names", [(None, ["x0", "x1"]), ("x", None)])
778+
def test_names_and_prefix_explicit_None(all_parsers, names, prefix, func):
779+
# GH42387
780+
f = StringIO("a,b\n1,2")
781+
expected = DataFrame({"x0": ["a", "1"], "x1": ["b", "2"]})
782+
parser = all_parsers
783+
result = getattr(parser, func)(f, names=names, sep=",", prefix=prefix, header=None)
784+
tm.assert_frame_equal(result, expected)
776785

777786

778787
def test_dict_keys_as_names(all_parsers):

pandas/tests/reshape/concat/test_append.py

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import datetime as dt
2-
from datetime import datetime
32
from itertools import combinations
43

54
import dateutil

pandas/tests/reshape/concat/test_append_common.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ def test_concatlike_datetimetz_to_object(self, tz_aware_fixture):
371371
)
372372

373373
res = dti1.append(dti3)
374-
# tm.assert_index_equal(res, exp)
374+
tm.assert_index_equal(res, exp)
375375

376376
dts1 = Series(dti1)
377377
dts3 = Series(dti3)

pandas/tests/reshape/concat/test_concat.py

-3
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,6 @@ def test_concat_copy(self):
7979
assert b.values.base is not None
8080

8181
def test_concat_with_group_keys(self):
82-
df = DataFrame(np.random.randn(4, 3))
83-
df2 = DataFrame(np.random.randn(4, 4))
84-
8582
# axis=0
8683
df = DataFrame(np.random.randn(3, 4))
8784
df2 = DataFrame(np.random.randn(4, 4))

pandas/tests/reshape/concat/test_dataframe.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ class TestDataFrameConcat:
1515
def test_concat_multiple_frames_dtypes(self):
1616

1717
# GH#2759
18-
A = DataFrame(data=np.ones((10, 2)), columns=["foo", "bar"], dtype=np.float64)
19-
B = DataFrame(data=np.ones((10, 2)), dtype=np.float32)
20-
results = concat((A, B), axis=1).dtypes
18+
df1 = DataFrame(data=np.ones((10, 2)), columns=["foo", "bar"], dtype=np.float64)
19+
df2 = DataFrame(data=np.ones((10, 2)), dtype=np.float32)
20+
results = concat((df1, df2), axis=1).dtypes
2121
expected = Series(
2222
[np.dtype("float64")] * 2 + [np.dtype("float32")] * 2,
2323
index=["foo", "bar", 0, 1],

pandas/tests/reshape/concat/test_index.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,18 @@ def test_concat_rename_index(self):
9696
tm.assert_frame_equal(result, exp)
9797
assert result.index.names == exp.index.names
9898

99-
@pytest.mark.parametrize("test_series", [True, False])
100-
def test_concat_copy_index(self, test_series, axis):
99+
def test_concat_copy_index_series(self, axis):
101100
# GH 29879
102-
if test_series:
103-
ser = Series([1, 2])
104-
comb = concat([ser, ser], axis=axis, copy=True)
105-
assert comb.index is not ser.index
106-
else:
107-
df = DataFrame([[1, 2], [3, 4]], columns=["a", "b"])
108-
comb = concat([df, df], axis=axis, copy=True)
109-
assert comb.index is not df.index
110-
assert comb.columns is not df.columns
101+
ser = Series([1, 2])
102+
comb = concat([ser, ser], axis=axis, copy=True)
103+
assert comb.index is not ser.index
104+
105+
def test_concat_copy_index_frame(self, axis):
106+
# GH 29879
107+
df = DataFrame([[1, 2], [3, 4]], columns=["a", "b"])
108+
comb = concat([df, df], axis=axis, copy=True)
109+
assert comb.index is not df.index
110+
assert comb.columns is not df.columns
111111

112112
def test_default_index(self):
113113
# is_series and ignore_index

pandas/tests/reshape/test_cut.py

+3-14
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ def test_simple():
3232
tm.assert_numpy_array_equal(result, expected, check_dtype=False)
3333

3434

35-
def test_bins():
36-
data = np.array([0.2, 1.4, 2.5, 6.2, 9.7, 2.1])
35+
@pytest.mark.parametrize("func", [list, np.array])
36+
def test_bins(func):
37+
data = func([0.2, 1.4, 2.5, 6.2, 9.7, 2.1])
3738
result, bins = cut(data, 3, retbins=True)
3839

3940
intervals = IntervalIndex.from_breaks(bins.round(3))
@@ -68,18 +69,6 @@ def test_no_right():
6869
tm.assert_almost_equal(bins, np.array([0.2, 2.575, 4.95, 7.325, 9.7095]))
6970

7071

71-
def test_array_like():
72-
data = [0.2, 1.4, 2.5, 6.2, 9.7, 2.1]
73-
result, bins = cut(data, 3, retbins=True)
74-
75-
intervals = IntervalIndex.from_breaks(bins.round(3))
76-
intervals = intervals.take([0, 0, 0, 1, 2, 0])
77-
expected = Categorical(intervals, ordered=True)
78-
79-
tm.assert_categorical_equal(result, expected)
80-
tm.assert_almost_equal(bins, np.array([0.1905, 3.36666667, 6.53333333, 9.7]))
81-
82-
8372
def test_bins_from_interval_index():
8473
c = cut(range(5), 3)
8574
expected = c

pandas/tests/scalar/timestamp/test_comparisons.py

+13
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,19 @@ def test_timestamp_compare_oob_dt64(self):
266266
assert Timestamp.max < other + us
267267
# Note: numpy gets the reversed comparison wrong
268268

269+
# GH-42794
270+
other = datetime(9999, 9, 9)
271+
assert Timestamp.min < other
272+
assert other > Timestamp.min
273+
assert Timestamp.max < other
274+
assert other > Timestamp.max
275+
276+
other = datetime(1, 1, 1)
277+
assert Timestamp.max > other
278+
assert other < Timestamp.max
279+
assert Timestamp.min > other
280+
assert other < Timestamp.min
281+
269282
def test_compare_zerodim_array(self):
270283
# GH#26916
271284
ts = Timestamp.now()

pandas/tests/series/methods/test_clip.py

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from datetime import datetime
2+
13
import numpy as np
24
import pytest
35

@@ -128,6 +130,15 @@ def test_clip_with_datetimes(self):
128130
)
129131
tm.assert_series_equal(result, expected)
130132

133+
def test_clip_with_timestamps_and_oob_datetimes(self):
134+
# GH-42794
135+
ser = Series([datetime(1, 1, 1), datetime(9999, 9, 9)])
136+
137+
result = ser.clip(lower=Timestamp.min, upper=Timestamp.max)
138+
expected = Series([Timestamp.min, Timestamp.max], dtype="object")
139+
140+
tm.assert_series_equal(result, expected)
141+
131142
def test_clip_pos_args_deprecation(self):
132143
# https://github.com/pandas-dev/pandas/issues/41485
133144
ser = Series([1, 2, 3])

0 commit comments

Comments
 (0)