Skip to content

Commit cdf2faa

Browse files
lukemanleyim-vinicius
authored and
im-vinicius
committed
BUG: merge_asof raising ValueError for read-only ndarrays (pandas-dev#53513)
* BUG: merge_asof raising ValueError for read-only ndarrays * gh refs
1 parent 1699890 commit cdf2faa

File tree

5 files changed

+35
-22
lines changed

5 files changed

+35
-22
lines changed

doc/source/whatsnew/v2.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ Reshaping
450450
^^^^^^^^^
451451
- Bug in :func:`crosstab` when ``dropna=False`` would not keep ``np.nan`` in the result (:issue:`10772`)
452452
- Bug in :func:`merge_asof` raising ``KeyError`` for extension dtypes (:issue:`52904`)
453+
- Bug in :func:`merge_asof` raising ``ValueError`` for data backed by read-only ndarrays (:issue:`53513`)
453454
- Bug in :meth:`DataFrame.agg` and :meth:`Series.agg` on non-unique columns would return incorrect type when dist-like argument passed in (:issue:`51099`)
454455
- Bug in :meth:`DataFrame.idxmin` and :meth:`DataFrame.idxmax`, where the axis dtype would be lost for empty frames (:issue:`53265`)
455456
- Bug in :meth:`DataFrame.merge` not merging correctly when having ``MultiIndex`` with single level (:issue:`52331`)

pandas/_libs/join.pyi

+12-12
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,28 @@ def outer_join_indexer(
5050
npt.NDArray[np.intp],
5151
]: ...
5252
def asof_join_backward_on_X_by_Y(
53-
left_values: np.ndarray, # asof_t[:]
54-
right_values: np.ndarray, # asof_t[:]
55-
left_by_values: np.ndarray, # by_t[:]
56-
right_by_values: np.ndarray, # by_t[:]
53+
left_values: np.ndarray, # ndarray[numeric_t]
54+
right_values: np.ndarray, # ndarray[numeric_t]
55+
left_by_values: np.ndarray, # ndarray[by_t]
56+
right_by_values: np.ndarray, # ndarray[by_t]
5757
allow_exact_matches: bool = ...,
5858
tolerance: np.number | float | None = ...,
5959
use_hashtable: bool = ...,
6060
) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.intp]]: ...
6161
def asof_join_forward_on_X_by_Y(
62-
left_values: np.ndarray, # asof_t[:]
63-
right_values: np.ndarray, # asof_t[:]
64-
left_by_values: np.ndarray, # by_t[:]
65-
right_by_values: np.ndarray, # by_t[:]
62+
left_values: np.ndarray, # ndarray[numeric_t]
63+
right_values: np.ndarray, # ndarray[numeric_t]
64+
left_by_values: np.ndarray, # ndarray[by_t]
65+
right_by_values: np.ndarray, # ndarray[by_t]
6666
allow_exact_matches: bool = ...,
6767
tolerance: np.number | float | None = ...,
6868
use_hashtable: bool = ...,
6969
) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.intp]]: ...
7070
def asof_join_nearest_on_X_by_Y(
71-
left_values: np.ndarray, # asof_t[:]
72-
right_values: np.ndarray, # asof_t[:]
73-
left_by_values: np.ndarray, # by_t[:]
74-
right_by_values: np.ndarray, # by_t[:]
71+
left_values: np.ndarray, # ndarray[numeric_t]
72+
right_values: np.ndarray, # ndarray[numeric_t]
73+
left_by_values: np.ndarray, # ndarray[by_t]
74+
right_by_values: np.ndarray, # ndarray[by_t]
7575
allow_exact_matches: bool = ...,
7676
tolerance: np.number | float | None = ...,
7777
use_hashtable: bool = ...,

pandas/_libs/join.pyx

+8-8
Original file line numberDiff line numberDiff line change
@@ -679,10 +679,10 @@ ctypedef fused by_t:
679679
uint64_t
680680

681681

682-
def asof_join_backward_on_X_by_Y(numeric_t[:] left_values,
683-
numeric_t[:] right_values,
684-
by_t[:] left_by_values,
685-
by_t[:] right_by_values,
682+
def asof_join_backward_on_X_by_Y(ndarray[numeric_t] left_values,
683+
ndarray[numeric_t] right_values,
684+
ndarray[by_t] left_by_values,
685+
ndarray[by_t] right_by_values,
686686
bint allow_exact_matches=True,
687687
tolerance=None,
688688
bint use_hashtable=True):
@@ -756,10 +756,10 @@ def asof_join_backward_on_X_by_Y(numeric_t[:] left_values,
756756
return left_indexer, right_indexer
757757

758758

759-
def asof_join_forward_on_X_by_Y(numeric_t[:] left_values,
760-
numeric_t[:] right_values,
761-
by_t[:] left_by_values,
762-
by_t[:] right_by_values,
759+
def asof_join_forward_on_X_by_Y(ndarray[numeric_t] left_values,
760+
ndarray[numeric_t] right_values,
761+
ndarray[by_t] left_by_values,
762+
ndarray[by_t] right_by_values,
763763
bint allow_exact_matches=1,
764764
tolerance=None,
765765
bint use_hashtable=True):

pandas/core/reshape/merge.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2142,13 +2142,13 @@ def injection(obj):
21422142
# we've verified above that no nulls exist
21432143
left_values = left_values._data
21442144
elif isinstance(left_values, ExtensionArray):
2145-
left_values = np.array(left_values)
2145+
left_values = left_values.to_numpy()
21462146

21472147
if isinstance(right_values, BaseMaskedArray):
21482148
# we've verified above that no nulls exist
21492149
right_values = right_values._data
21502150
elif isinstance(right_values, ExtensionArray):
2151-
right_values = np.array(right_values)
2151+
right_values = right_values.to_numpy()
21522152

21532153
# a "by" parameter requires special handling
21542154
if self.left_by is not None:

pandas/tests/reshape/merge/test_merge_asof.py

+12
Original file line numberDiff line numberDiff line change
@@ -1627,3 +1627,15 @@ def test_merge_asof_extension_dtype(dtype):
16271627
)
16281628
expected = expected.astype({"join_col": dtype})
16291629
tm.assert_frame_equal(result, expected)
1630+
1631+
1632+
def test_merge_asof_read_only_ndarray():
1633+
# GH 53513
1634+
left = pd.Series([2], index=[2], name="left")
1635+
right = pd.Series([1], index=[1], name="right")
1636+
# set to read-only
1637+
left.index.values.flags.writeable = False
1638+
right.index.values.flags.writeable = False
1639+
result = merge_asof(left, right, left_index=True, right_index=True)
1640+
expected = pd.DataFrame({"left": [2], "right": [1]}, index=[2])
1641+
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)