Skip to content

Commit c2ebf4c

Browse files
committed
Merge pull request #7951 from jreback/index_follow
DOC/TST: index followup
2 parents c7bfb4e + 1f64bc8 commit c2ebf4c

File tree

8 files changed

+128
-22
lines changed

8 files changed

+128
-22
lines changed

doc/source/api.rst

+37-10
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ Constructor
235235

236236
Series
237237

238-
Attributes and underlying data
239-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
238+
Attributes
239+
~~~~~~~~~~
240240
**Axes**
241241
* **index**: axis labels
242242

@@ -246,6 +246,14 @@ Attributes and underlying data
246246
Series.values
247247
Series.dtype
248248
Series.ftype
249+
Series.shape
250+
Series.size
251+
Series.nbytes
252+
Series.ndim
253+
Series.strides
254+
Series.itemsize
255+
Series.base
256+
Series.T
249257

250258
Conversion
251259
~~~~~~~~~~
@@ -1087,11 +1095,36 @@ used before calling these methods directly.**
10871095

10881096
Index
10891097

1098+
Attributes
1099+
~~~~~~~~~~
1100+
1101+
.. autosummary::
1102+
:toctree: generated/
1103+
1104+
Index.values
1105+
Index.is_monotonic
1106+
Index.is_unique
1107+
Index.dtype
1108+
Index.inferred_type
1109+
Index.is_all_dates
1110+
Index.shape
1111+
Index.size
1112+
Index.nbytes
1113+
Index.ndim
1114+
Index.strides
1115+
Index.itemsize
1116+
Index.base
1117+
Index.T
1118+
10901119
Modifying and Computations
10911120
~~~~~~~~~~~~~~~~~~~~~~~~~~
10921121
.. autosummary::
10931122
:toctree: generated/
10941123

1124+
Index.all
1125+
Index.any
1126+
Index.argmin
1127+
Index.argmax
10951128
Index.copy
10961129
Index.delete
10971130
Index.diff
@@ -1101,6 +1134,8 @@ Modifying and Computations
11011134
Index.factorize
11021135
Index.identical
11031136
Index.insert
1137+
Index.min
1138+
Index.max
11041139
Index.order
11051140
Index.reindex
11061141
Index.repeat
@@ -1161,14 +1196,6 @@ Selecting
11611196
Index.slice_indexer
11621197
Index.slice_locs
11631198

1164-
Properties
1165-
~~~~~~~~~~
1166-
.. autosummary::
1167-
:toctree: generated/
1168-
1169-
Index.is_monotonic
1170-
Index.is_numeric
1171-
11721199
.. _api.datetimeindex:
11731200

11741201
DatetimeIndex

doc/source/io.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -2101,7 +2101,8 @@ any pickled pandas object (or any other pickled object) from file:
21012101

21022102
.. warning::
21032103

2104-
In 0.13, pickle preserves compatibility with pickles created prior to 0.13. These must
2104+
Several internal refactorings, 0.13 (:ref:`Series Refactoring <whatsnew_0130.refactoring>`), and 0.15 (:ref:`Index Refactoring <whatsnew_0150.refactoring>`),
2105+
preserve compatibility with pickles created prior to these versions. However, these must
21052106
be read with ``pd.read_pickle``, rather than the default python ``pickle.load``.
21062107
See `this question <http://stackoverflow.com/questions/20444593/pandas-compiled-from-source-default-pickle-behavior-changed>`__
21072108
for a detailed explanation.

doc/source/v0.15.0.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,11 @@ Internal Refactoring
169169

170170
In 0.15.0 ``Index`` has internally been refactored to no longer sub-class ``ndarray``
171171
but instead subclass ``PandasObject``, similarly to the rest of the pandas objects. This change allows very easy sub-classing and creation of new index types. This should be
172-
a transparent change with only very limited API implications (:issue:`5080`,:issue:`7439`,:issue:`7796`)
172+
a transparent change with only very limited API implications (:issue:`5080`, :issue:`7439`, :issue:`7796`)
173173

174174
- you may need to unpickle pandas version < 0.15.0 pickles using ``pd.read_pickle`` rather than ``pickle.load``. See :ref:`pickle docs <io.pickle>`
175-
- when plotting with a ``PeriodIndex``. The ``matplotlib`` internal axes will now be arrays of ``Period`` rather than a ``PeriodIndex``. (this is similar to how a ``DatetimeIndex`` passess arrays of ``datetimes`` now)
175+
- when plotting with a ``PeriodIndex``. The ``matplotlib`` internal axes will now be arrays of ``Period`` rather than a ``PeriodIndex``. (this is similar to how a ``DatetimeIndex`` passes arrays of ``datetimes`` now)
176+
- MultiIndexes will now raise similary to other pandas objects w.r.t. truth testing, See :ref:`here <gotchas.truth>` (:issue:`7897`).
176177

177178
.. _whatsnew_0150.cat:
178179

pandas/core/base.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,34 @@ def max(self):
313313
""" The maximum value of the object """
314314
return nanops.nanmax(self.values)
315315

316+
def argmax(self, axis=None):
317+
"""
318+
return a ndarray of the maximum argument indexer
319+
320+
See also
321+
--------
322+
numpy.ndarray.argmax
323+
"""
324+
return nanops.nanargmax(self.values)
325+
316326
def min(self):
317327
""" The minimum value of the object """
318328
return nanops.nanmin(self.values)
319329

330+
def argmin(self, axis=None):
331+
"""
332+
return a ndarray of the minimum argument indexer
333+
334+
See also
335+
--------
336+
numpy.ndarray.argmin
337+
"""
338+
return nanops.nanargmin(self.values)
339+
340+
def hasnans(self):
341+
""" return if I have any nans; enables various perf speedups """
342+
return com.isnull(self).any()
343+
320344
def value_counts(self, normalize=False, sort=True, ascending=False,
321345
bins=None, dropna=True):
322346
"""
@@ -554,10 +578,11 @@ def argmin(self, axis=None):
554578
numpy.ndarray.argmin
555579
"""
556580

557-
##### FIXME: need some tests (what do do if all NaT?)
558581
i8 = self.asi8
559582
if self.hasnans:
560583
mask = i8 == tslib.iNaT
584+
if mask.all():
585+
return -1
561586
i8 = i8.copy()
562587
i8[mask] = np.iinfo('int64').max
563588
return i8.argmin()
@@ -596,10 +621,11 @@ def argmax(self, axis=None):
596621
numpy.ndarray.argmax
597622
"""
598623

599-
#### FIXME: need some tests (what do do if all NaT?)
600624
i8 = self.asi8
601625
if self.hasnans:
602626
mask = i8 == tslib.iNaT
627+
if mask.all():
628+
return -1
603629
i8 = i8.copy()
604630
i8[mask] = 0
605631
return i8.argmax()

pandas/core/index.py

+15
Original file line numberDiff line numberDiff line change
@@ -560,13 +560,15 @@ def _mpl_repr(self):
560560

561561
@property
562562
def is_monotonic(self):
563+
""" return if the index has monotonic (only equaly or increasing) values """
563564
return self._engine.is_monotonic
564565

565566
def is_lexsorted_for_tuple(self, tup):
566567
return True
567568

568569
@cache_readonly(allow_setting=True)
569570
def is_unique(self):
571+
""" return if the index has unique values """
570572
return self._engine.is_unique
571573

572574
def is_integer(self):
@@ -788,6 +790,7 @@ def _get_level_number(self, level):
788790

789791
@cache_readonly
790792
def inferred_type(self):
793+
""" return a string of the type inferred from the values """
791794
return lib.infer_dtype(self)
792795

793796
def is_type_compatible(self, typ):
@@ -835,6 +838,13 @@ def __setstate__(self, state):
835838
def __deepcopy__(self, memo={}):
836839
return self.copy(deep=True)
837840

841+
def __nonzero__(self):
842+
raise ValueError("The truth value of a {0} is ambiguous. "
843+
"Use a.empty, a.bool(), a.item(), a.any() or a.all()."
844+
.format(self.__class__.__name__))
845+
846+
__bool__ = __nonzero__
847+
838848
def __contains__(self, key):
839849
hash(key)
840850
# work around some kind of odd cython bug
@@ -2143,6 +2153,11 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=False, *
21432153
def inferred_type(self):
21442154
return 'integer'
21452155

2156+
@cache_readonly
2157+
def hasnans(self):
2158+
# by definition
2159+
return False
2160+
21462161
@property
21472162
def asi8(self):
21482163
# do not cache or you'll create a memory leak

pandas/tests/test_base.py

+21
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,27 @@ def test_nanops(self):
261261
# check DatetimeIndex non-monotonic path
262262
self.assertEqual(getattr(obj, op)(), datetime(2011, 11, 1))
263263

264+
# argmin/max
265+
obj = Index(np.arange(5,dtype='int64'))
266+
self.assertEqual(obj.argmin(),0)
267+
self.assertEqual(obj.argmax(),4)
268+
269+
obj = Index([np.nan, 1, np.nan, 2])
270+
self.assertEqual(obj.argmin(),1)
271+
self.assertEqual(obj.argmax(),3)
272+
273+
obj = Index([np.nan])
274+
self.assertEqual(obj.argmin(),-1)
275+
self.assertEqual(obj.argmax(),-1)
276+
277+
obj = Index([pd.NaT, datetime(2011, 11, 1), datetime(2011,11,2),pd.NaT])
278+
self.assertEqual(obj.argmin(),1)
279+
self.assertEqual(obj.argmax(),2)
280+
281+
obj = Index([pd.NaT])
282+
self.assertEqual(obj.argmin(),-1)
283+
self.assertEqual(obj.argmax(),-1)
284+
264285
def test_value_counts_unique_nunique(self):
265286
for o in self.objs:
266287
klass = type(o)

pandas/tests/test_index.py

+22
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ def test_numeric_compat(self):
7474
"cannot perform floor division",
7575
lambda : 1 // idx)
7676

77+
def test_boolean_context_compat(self):
78+
79+
# boolean context compat
80+
idx = self.create_index()
81+
def f():
82+
if idx:
83+
pass
84+
tm.assertRaisesRegexp(ValueError,'The truth value of a',f)
85+
7786
class TestIndex(Base, tm.TestCase):
7887
_holder = Index
7988
_multiprocess_can_split_ = True
@@ -1656,6 +1665,19 @@ def setUp(self):
16561665
def create_index(self):
16571666
return self.index
16581667

1668+
def test_boolean_context_compat2(self):
1669+
1670+
# boolean context compat
1671+
# GH7897
1672+
i1 = MultiIndex.from_tuples([('A', 1), ('A', 2)])
1673+
i2 = MultiIndex.from_tuples([('A', 1), ('A', 3)])
1674+
common = i1.intersection(i2)
1675+
1676+
def f():
1677+
if common:
1678+
pass
1679+
tm.assertRaisesRegexp(ValueError,'The truth value of a',f)
1680+
16591681
def test_hash_error(self):
16601682
with tm.assertRaisesRegexp(TypeError,
16611683
"unhashable type: %r" %

pandas/tseries/index.py

-7
Original file line numberDiff line numberDiff line change
@@ -1490,13 +1490,6 @@ def searchsorted(self, key, side='left'):
14901490
def is_type_compatible(self, typ):
14911491
return typ == self.inferred_type or typ == 'datetime'
14921492

1493-
def argmin(self):
1494-
# hack to workaround argmin failure
1495-
try:
1496-
return self.values.argmin()
1497-
except Exception: # pragma: no cover
1498-
return self.asi8.argmin()
1499-
15001493
@property
15011494
def inferred_type(self):
15021495
# b/c datetime is represented as microseconds since the epoch, make

0 commit comments

Comments
 (0)