Skip to content

Commit 224ee15

Browse files
committed
ENH: Add is_array_like method
Used for abstracting checks in DataFrame.merge, but the function itself can be quite useful.
1 parent 7e70d33 commit 224ee15

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

pandas/core/dtypes/api.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
is_dict_like,
5656
is_iterator,
5757
is_file_like,
58+
is_array_like,
5859
is_list_like,
5960
is_hashable,
6061
is_named_tuple)

pandas/core/dtypes/inference.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,26 @@ def is_list_like(obj):
267267
not isinstance(obj, string_and_binary_types))
268268

269269

270+
def is_array_like(obj):
271+
"""
272+
Check if the object is array-like.
273+
274+
For an object to be considered array-like, it must be list-like and
275+
have a `dtype` attribute.
276+
277+
Parameters
278+
----------
279+
obj : The object to check.
280+
281+
Returns
282+
-------
283+
is_array_like : bool
284+
Whether `obj` has array-like properties.
285+
"""
286+
287+
return is_list_like(obj) and hasattr(obj, "dtype")
288+
289+
270290
def is_nested_list_like(obj):
271291
"""
272292
Check if the object is list-like, and that all of its elements

pandas/core/reshape/merge.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
is_datetime64_dtype,
1919
needs_i8_conversion,
2020
is_int64_dtype,
21+
is_array_like,
2122
is_categorical_dtype,
2223
is_integer_dtype,
2324
is_float_dtype,
@@ -816,10 +817,9 @@ def _get_merge_keys(self):
816817
left_drop = []
817818

818819
left, right = self.left, self.right
819-
list_types = (np.ndarray, Series, Index)
820820

821-
is_lkey = lambda x: isinstance(x, list_types) and len(x) == len(left)
822-
is_rkey = lambda x: isinstance(x, list_types) and len(x) == len(right)
821+
is_lkey = lambda x: is_array_like(x) and len(x) == len(left)
822+
is_rkey = lambda x: is_array_like(x) and len(x) == len(right)
823823

824824
# Note that pd.merge_asof() has separate 'on' and 'by' parameters. A
825825
# user could, for example, request 'left_index' and 'left_by'. In a

pandas/tests/dtypes/test_inference.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,23 @@ def test_is_list_like_fails(ll):
7878
assert not inference.is_list_like(ll)
7979

8080

81+
def test_is_array_like():
82+
assert inference.is_array_like(Series([]))
83+
assert inference.is_array_like(Series([1, 2]))
84+
assert inference.is_array_like(np.array(["a", "b"]))
85+
assert inference.is_array_like(Index(["2016-01-01"]))
86+
87+
class DtypeList(list):
88+
dtype = "special"
89+
90+
assert inference.is_array_like(DtypeList())
91+
92+
assert not inference.is_array_like([1, 2, 3])
93+
assert not inference.is_array_like(tuple())
94+
assert not inference.is_array_like("foo")
95+
assert not inference.is_array_like(123)
96+
97+
8198
@pytest.mark.parametrize('inner', [
8299
[], [1], (1, ), (1, 2), {'a': 1}, set([1, 'a']), Series([1]),
83100
Series([]), Series(['a']).str, (x for x in range(5))

0 commit comments

Comments
 (0)