Repository: pandas-dev/pandas

Issue:
Datetime/Timedelta/Period Index min, argmin, max, argmax have `axis` kwarg
Presumably shouldn't, or at least should raise if non-None.


Discussion:
Hi,
In which folder/file are these defined? And could you please provide some more detail? 
> In which folder/file are these defined?

These methods are defined in pandas/core/indexes/datetimelike.py

> And could you please provide some more detail?

DatetimeIndex/TimedeltaIndex/PeriodIndex are each 1-dimensional, so an `axis` argument doesn't really make sense.  Also it is ignored if the user passes it, which is pretty much never good.

It's conceivable that the argument is there in order to keep the method's signature consistent with some other class's methods, but someone more knowledgeable than me will have to weigh in on that.
@anjalibhavan the code we're talking about is for example: https://github.com/pandas-dev/pandas/blob/master/pandas/core/indexes/datetimelike.py#L451

Personally I think we should get rid of them, and I don't think it's worth adding a deprecation warning, as the functions seem to accept `*args` and `**kwargs` and the code using that (if anyone ever did that) won't fail.

@gfyoung @jreback are we missing something here? 
@datapythonista there is also `take` function at https://github.com/pandas-dev/pandas/blob/master/pandas/core/indexes/datetimelike.py#L375 where axis argument has no usage. Let me know if that too has to be removed.
I just have removed the the `axis` argument and not `args` and `kwargs`
@datapythonista : We perform validation on `args` and `kwargs` on the very first line for compatibility with `numpy`.  Thus, they serve a somewhat different purpose than in most other cases.  As a result, I am hesitant to just "remove" the argument without some kind of deprecation first.
thanks @5hirish, looks like it's the same case. @jbrockmendel I'll leave it to you whether to add it to the issue description or not, may be I'm missing something.

@gfyoung I didn't see that. Then it probably makes sense to deprecate first. But I don't think if there will be any code out there using a parameter that has no effect.
> But I don't think if there will be any code out there using a parameter that has no effect.

@datapythonista : Well, better safe than sorry 🙂.  That's all I'll say, since we seem to be in agreement that we should go with deprecation instead of removal.
@datapythonista Let me know I can revert the removals and add deprecation warnings if I understand correctly. I can see an example here: https://github.com/pandas-dev/pandas/blob/master/pandas/core/indexes/datetimelike.py#L399
this is not possible because of numpy compatibility. This is also appropriately documented. Is there an issue there?

Resolving patch:
diff --git a/pandas/compat/numpy/function.py b/pandas/compat/numpy/function.py
--- a/pandas/compat/numpy/function.py
+++ b/pandas/compat/numpy/function.py
@@ -360,3 +360,24 @@ def validate_resampler_func(method, args, kwargs):
                 "{func}() instead".format(func=method)))
         else:
             raise TypeError("too many arguments passed in")
+
+
+def validate_minmax_axis(axis):
+    """
+    Ensure that the axis argument passed to min, max, argmin, or argmax is
+    zero or None, as otherwise it will be incorrectly ignored.
+
+    Parameters
+    ----------
+    axis : int or None
+
+    Raises
+    ------
+    ValueError
+    """
+    ndim = 1  # hard-coded for Index
+    if axis is None:
+        return
+    if axis >= ndim or (axis < 0 and ndim + axis < 0):
+        raise ValueError("`axis` must be fewer than the number of "
+                         "dimensions ({ndim})".format(ndim=ndim))
diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py
--- a/pandas/core/indexes/datetimelike.py
+++ b/pandas/core/indexes/datetimelike.py
@@ -431,6 +431,7 @@ def min(self, axis=None, *args, **kwargs):
         numpy.ndarray.min
         """
         nv.validate_min(args, kwargs)
+        nv.validate_minmax_axis(axis)
 
         try:
             i8 = self.asi8
@@ -459,6 +460,7 @@ def argmin(self, axis=None, *args, **kwargs):
         numpy.ndarray.argmin
         """
         nv.validate_argmin(args, kwargs)
+        nv.validate_minmax_axis(axis)
 
         i8 = self.asi8
         if self.hasnans:
@@ -479,6 +481,7 @@ def max(self, axis=None, *args, **kwargs):
         numpy.ndarray.max
         """
         nv.validate_max(args, kwargs)
+        nv.validate_minmax_axis(axis)
 
         try:
             i8 = self.asi8
@@ -507,6 +510,7 @@ def argmax(self, axis=None, *args, **kwargs):
         numpy.ndarray.argmax
         """
         nv.validate_argmax(args, kwargs)
+        nv.validate_minmax_axis(axis)
 
         i8 = self.asi8
         if self.hasnans:


Test patch:
diff --git a/pandas/tests/indexes/datetimelike.py b/pandas/tests/indexes/datetimelike.py
--- a/pandas/tests/indexes/datetimelike.py
+++ b/pandas/tests/indexes/datetimelike.py
@@ -8,6 +8,18 @@
 
 class DatetimeLike(Base):
 
+    def test_argmax_axis_invalid(self):
+        # GH#23081
+        rng = self.create_index()
+        with pytest.raises(ValueError):
+            rng.argmax(axis=1)
+        with pytest.raises(ValueError):
+            rng.argmin(axis=2)
+        with pytest.raises(ValueError):
+            rng.min(axis=-2)
+        with pytest.raises(ValueError):
+            rng.max(axis=-3)
+
     def test_can_hold_identifiers(self):
         idx = self.create_index()
         key = idx[0]