Repository: cupy/cupy

Issue:
cupy.nanmedian bug report 
I may found a cupy.nanmedian bug.
Numpy result and Cupy result are different.
Could you check below codes?

Numpy:
```
import cupy as cp
import numpy as np
xp = np
x,y = xp.meshgrid(xp.arange(0, 6),xp.arange(0, 6)) 
R = xp.sqrt((x-3)**2 + (y-3)**2)
a = R>2
a = a * R
a[a==0]=xp.nan
b = xp.tile(a,(6,6,1,1))
c = xp.nanmedian(b,axis=[2,3]).shape
print(c) # returns (6, 6)
```

Cupy:
```
import cupy as cp
import numpy as np
xp = cp
x,y = xp.meshgrid(xp.arange(0, 6),xp.arange(0, 6)) 
R = xp.sqrt((x-3)**2 + (y-3)**2)
a = R>2
a = a * R
a[a==0]=xp.nan
b = xp.tile(a,(6,6,1,1))
c = xp.nanmedian(b,axis=[2,3]).shape
print(c) # returns (6, 6, 6, 6)
```

Environment:
OS                           : Linux-4.15.0-143-generic-x86_64-with-debian-buster-sid
Python Version               : 3.7.9
CuPy Version                 : 9.1.0
CuPy Platform                : NVIDIA CUDA
NumPy Version                : 1.20.3
SciPy Version                : 1.6.3
Cython Build Version         : 0.29.23
Cython Runtime Version       : None
CUDA Root                    : /home/nishiumi/anaconda3/envs/py37
nvcc PATH                    : None
CUDA Build Version           : 11020
CUDA Driver Version          : 11020
CUDA Runtime Version         : 11020
cuBLAS Version               : 11401
cuFFT Version                : 10401
cuRAND Version               : 10203
cuSOLVER Version             : (11, 1, 0)
cuSPARSE Version             : 11401
NVRTC Version                : (11, 2)
Thrust Version               : 101000
CUB Build Version            : 101000
Jitify Build Version         : <unknown>
cuDNN Build Version          : 8100
cuDNN Version                : 8001
NCCL Build Version           : None
NCCL Runtime Version         : None
cuTENSOR Version             : None
cuSPARSELt Build Version     : None
Device 0 Name                : TITAN RTX
Device 0 Compute Capability  : 75
Device 0 PCI Bus ID          : 0000:1A:00.0
Device 1 Name                : TITAN RTX
Device 1 Compute Capability  : 75
Device 1 PCI Bus ID          : 0000:68:00.0




Discussion:
Thanks for reporting! This is indeed a bug. It seems that we haven't followed the spec added in NumPy 1.9.0:

https://numpy.org/doc/stable/reference/generated/numpy.nanmedian.html

> A sequence of axes is supported since version 1.9.0.

I think the same thing can be said for `numpy.median` too.
Inaddition to it,  `cupy.nanmean`, `cupy.median`and `cupy.mean` has probably same problem because of the same reason.
Looks that a sequence of axes is inappropriately assumed to be a tuple.
https://github.com/cupy/cupy/blob/a0790a47cbd8956c210469b398f3e1a1b1b4ebb2/cupy/_core/_routines_statistics.pyx#L446


As for `cupy.nanmean`, `cupy.median` and `cupy.mean`, it seems that a sequence of axes works and the document does not properly describe `axis` parameter.

Resolving patch:
diff --git a/cupy/_statistics/meanvar.py b/cupy/_statistics/meanvar.py
--- a/cupy/_statistics/meanvar.py
+++ b/cupy/_statistics/meanvar.py
@@ -12,8 +12,8 @@ def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
 
     Args:
         a (cupy.ndarray): Array to compute the median.
-        axis (int): Axis along which the medians are computed. The flattened
-            array is used by default.
+        axis (int, sequence of int or None): Axis along which the medians are
+             computed. The flattened array is used by default.
         out (cupy.ndarray): Output array.
         overwrite_input (bool): If ``True``, then allow use of memory of input
             array a for calculations. The input array will be modified by the
@@ -41,8 +41,8 @@ def nanmedian(a, axis=None, out=None, overwrite_input=False, keepdims=False):
 
     Args:
         a (cupy.ndarray): Array to compute the median.
-        axis (int): Axis along which the medians are computed. The flattened
-            array is used by default.
+        axis (int, sequence of int or None): Axis along which the medians are
+            computed. The flattened array is used by default.
         out (cupy.ndarray): Output array.
         overwrite_input (bool): If ``True``, then allow use of memory of input
             array a for calculations. The input array will be modified by the
@@ -142,8 +142,8 @@ def mean(a, axis=None, dtype=None, out=None, keepdims=False):
 
     Args:
         a (cupy.ndarray): Array to compute mean.
-        axis (int): Along which axis to compute mean. The flattened array is
-            used by default.
+        axis (int, sequence of int or None): Along which axis to compute mean.
+            The flattened array is used by default.
         dtype: Data type specifier.
         out (cupy.ndarray): Output array.
         keepdims (bool): If ``True``, the axis is remained as an axis of
@@ -210,8 +210,8 @@ def nanmean(a, axis=None, dtype=None, out=None, keepdims=False):
 
     Args:
         a (cupy.ndarray): Array to compute mean.
-        axis (int): Along which axis to compute mean. The flattened array is
-            used by default.
+        axis (int, sequence of int or None): Along which axis to compute mean.
+            The flattened array is used by default.
         dtype: Data type specifier.
         out (cupy.ndarray): Output array.
         keepdims (bool): If ``True``, the axis is remained as an axis of


Test patch:
diff --git a/tests/cupy_tests/statistics_tests/test_meanvar.py b/tests/cupy_tests/statistics_tests/test_meanvar.py
--- a/tests/cupy_tests/statistics_tests/test_meanvar.py
+++ b/tests/cupy_tests/statistics_tests/test_meanvar.py
@@ -86,7 +86,7 @@ def test_median_axis_sequence(self, xp, dtype):
 @testing.parameterize(
     *testing.product({
         'shape': [(3, 4, 5)],
-        'axis': [None, 0, 1, -1, (0, 1), (0, 2), (-1, -2)],
+        'axis': [None, 0, 1, -1, (0, 1), (0, 2), (-1, -2), [0, 1]],
         'keepdims': [True, False],
         'overwrite_input': [True, False]
     })