Skip to content

Commit 1544f50

Browse files
committed
DEPR: deprecate .ix in favor of .loc/.iloc
closes pandas-dev#14218 closes pandas-dev#15116
1 parent 362e78d commit 1544f50

File tree

90 files changed

+1657
-1399
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+1657
-1399
lines changed

doc/source/advanced.rst

+6-17
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ of tuples:
230230
Advanced indexing with hierarchical index
231231
-----------------------------------------
232232

233-
Syntactically integrating ``MultiIndex`` in advanced indexing with ``.loc/.ix`` is a
233+
Syntactically integrating ``MultiIndex`` in advanced indexing with ``.loc`` is a
234234
bit challenging, but we've made every effort to do so. for example the
235235
following works as you would expect:
236236

@@ -258,7 +258,7 @@ Passing a list of labels or tuples works similar to reindexing:
258258

259259
.. ipython:: python
260260
261-
df.ix[[('bar', 'two'), ('qux', 'one')]]
261+
df.loc[[('bar', 'two'), ('qux', 'one')]]
262262
263263
.. _advanced.mi_slicers:
264264

@@ -604,7 +604,7 @@ intended to work on boolean indices and may return unexpected results.
604604
605605
ser = pd.Series(np.random.randn(10))
606606
ser.take([False, False, True, True])
607-
ser.ix[[0, 1]]
607+
ser.iloc[[0, 1]]
608608
609609
Finally, as a small note on performance, because the ``take`` method handles
610610
a narrower range of inputs, it can offer performance that is a good deal
@@ -620,7 +620,7 @@ faster than fancy indexing.
620620
timeit arr.take(indexer, axis=0)
621621

622622
ser = pd.Series(arr[:, 0])
623-
timeit ser.ix[indexer]
623+
timeit ser.iloc[indexer]
624624
timeit ser.take(indexer)
625625

626626
.. _indexing.index_types:
@@ -661,7 +661,7 @@ Setting the index, will create create a ``CategoricalIndex``
661661
df2 = df.set_index('B')
662662
df2.index
663663
664-
Indexing with ``__getitem__/.iloc/.loc/.ix`` works similarly to an ``Index`` with duplicates.
664+
Indexing with ``__getitem__/.iloc/.loc`` works similarly to an ``Index`` with duplicates.
665665
The indexers MUST be in the category or the operation will raise.
666666

667667
.. ipython:: python
@@ -759,14 +759,12 @@ same.
759759
sf = pd.Series(range(5), index=indexf)
760760
sf
761761
762-
Scalar selection for ``[],.ix,.loc`` will always be label based. An integer will match an equal float index (e.g. ``3`` is equivalent to ``3.0``)
762+
Scalar selection for ``[],.loc`` will always be label based. An integer will match an equal float index (e.g. ``3`` is equivalent to ``3.0``)
763763
764764
.. ipython:: python
765765
766766
sf[3]
767767
sf[3.0]
768-
sf.ix[3]
769-
sf.ix[3.0]
770768
sf.loc[3]
771769
sf.loc[3.0]
772770
@@ -783,7 +781,6 @@ Slicing is ALWAYS on the values of the index, for ``[],ix,loc`` and ALWAYS posit
783781
.. ipython:: python
784782
785783
sf[2:4]
786-
sf.ix[2:4]
787784
sf.loc[2:4]
788785
sf.iloc[2:4]
789786
@@ -813,14 +810,6 @@ In non-float indexes, slicing using floats will raise a ``TypeError``
813810
In [3]: pd.Series(range(5)).iloc[3.0]
814811
TypeError: cannot do positional indexing on <class 'pandas.indexes.range.RangeIndex'> with these indexers [3.0] of <type 'float'>
815812
816-
Further the treatment of ``.ix`` with a float indexer on a non-float index, will be label based, and thus coerce the index.
817-
818-
.. ipython:: python
819-
820-
s2 = pd.Series([1, 2, 3], index=list('abc'))
821-
s2
822-
s2.ix[1.0] = 10
823-
s2
824813
825814
Here is a typical use-case for using this type of indexing. Imagine that you have a somewhat
826815
irregular timedelta-like indexing scheme, but the data is recorded as floats. This could for

doc/source/api.rst

+3-6
Original file line numberDiff line numberDiff line change
@@ -268,13 +268,12 @@ Indexing, iteration
268268
Series.get
269269
Series.at
270270
Series.iat
271-
Series.ix
272271
Series.loc
273272
Series.iloc
274273
Series.__iter__
275274
Series.iteritems
276275

277-
For more information on ``.at``, ``.iat``, ``.ix``, ``.loc``, and
276+
For more information on ``.at``, ``.iat``, ``.loc``, and
278277
``.iloc``, see the :ref:`indexing documentation <indexing>`.
279278

280279
Binary operator functions
@@ -774,7 +773,6 @@ Indexing, iteration
774773
DataFrame.head
775774
DataFrame.at
776775
DataFrame.iat
777-
DataFrame.ix
778776
DataFrame.loc
779777
DataFrame.iloc
780778
DataFrame.insert
@@ -791,7 +789,7 @@ Indexing, iteration
791789
DataFrame.mask
792790
DataFrame.query
793791

794-
For more information on ``.at``, ``.iat``, ``.ix``, ``.loc``, and
792+
For more information on ``.at``, ``.iat``, ``.loc``, and
795793
``.iloc``, see the :ref:`indexing documentation <indexing>`.
796794

797795

@@ -1090,7 +1088,6 @@ Indexing, iteration, slicing
10901088

10911089
Panel.at
10921090
Panel.iat
1093-
Panel.ix
10941091
Panel.loc
10951092
Panel.iloc
10961093
Panel.__iter__
@@ -1100,7 +1097,7 @@ Indexing, iteration, slicing
11001097
Panel.major_xs
11011098
Panel.minor_xs
11021099

1103-
For more information on ``.at``, ``.iat``, ``.ix``, ``.loc``, and
1100+
For more information on ``.at``, ``.iat``, ``.loc``, and
11041101
``.iloc``, see the :ref:`indexing documentation <indexing>`.
11051102

11061103
Binary operator functions

doc/source/basics.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ either match on the *index* or *columns* via the **axis** keyword:
145145
'two' : pd.Series(np.random.randn(4), index=['a', 'b', 'c', 'd']),
146146
'three' : pd.Series(np.random.randn(3), index=['b', 'c', 'd'])})
147147
df
148-
row = df.ix[1]
148+
row = df.iloc[1]
149149
column = df['two']
150150
151151
df.sub(row, axis='columns')
@@ -556,7 +556,7 @@ course):
556556
series[::2] = np.nan
557557
series.describe()
558558
frame = pd.DataFrame(np.random.randn(1000, 5), columns=['a', 'b', 'c', 'd', 'e'])
559-
frame.ix[::2] = np.nan
559+
frame.iloc[::2] = np.nan
560560
frame.describe()
561561
562562
You can select specific percentiles to include in the output:
@@ -1081,7 +1081,7 @@ objects either on the DataFrame's index or columns using the ``axis`` argument:
10811081

10821082
.. ipython:: python
10831083
1084-
df.align(df2.ix[0], axis=1)
1084+
df.align(df2.iloc[0], axis=1)
10851085
10861086
.. _basics.reindex_fill:
10871087

doc/source/categorical.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ Pivot tables:
482482
Data munging
483483
------------
484484

485-
The optimized pandas data access methods ``.loc``, ``.iloc``, ``.ix`` ``.at``, and ``.iat``,
485+
The optimized pandas data access methods ``.loc``, ``.iloc``, ``.at``, and ``.iat``,
486486
work as normal. The only difference is the return type (for getting) and
487487
that only values already in `categories` can be assigned.
488488

@@ -501,7 +501,6 @@ the ``category`` dtype is preserved.
501501
df.iloc[2:4,:]
502502
df.iloc[2:4,:].dtypes
503503
df.loc["h":"j","cats"]
504-
df.ix["h":"j",0:1]
505504
df[df["cats"] == "b"]
506505
507506
An example where the category type is not preserved is if you take one single row: the

doc/source/computation.rst

+5-5
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ in order to have a valid result.
8484
.. ipython:: python
8585
8686
frame = pd.DataFrame(np.random.randn(20, 3), columns=['a', 'b', 'c'])
87-
frame.ix[:5, 'a'] = np.nan
88-
frame.ix[5:10, 'b'] = np.nan
87+
frame.loc[frame.index[:5], 'a'] = np.nan
88+
frame.loc[frame.index[5:10], 'b'] = np.nan
8989
9090
frame.cov()
9191
@@ -120,7 +120,7 @@ All of these are currently computed using pairwise complete observations.
120120
.. ipython:: python
121121
122122
frame = pd.DataFrame(np.random.randn(1000, 5), columns=['a', 'b', 'c', 'd', 'e'])
123-
frame.ix[::2] = np.nan
123+
frame.iloc[::2] = np.nan
124124
125125
# Series with Series
126126
frame['a'].corr(frame['b'])
@@ -137,8 +137,8 @@ Like ``cov``, ``corr`` also supports the optional ``min_periods`` keyword:
137137
.. ipython:: python
138138
139139
frame = pd.DataFrame(np.random.randn(20, 3), columns=['a', 'b', 'c'])
140-
frame.ix[:5, 'a'] = np.nan
141-
frame.ix[5:10, 'b'] = np.nan
140+
frame.loc[frame.index[:5], 'a'] = np.nan
141+
frame.loc[frame.index[5:10], 'b'] = np.nan
142142
143143
frame.corr()
144144

doc/source/cookbook.rst

+9-12
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,19 @@ An if-then on one column
6666

6767
.. ipython:: python
6868
69-
df.ix[df.AAA >= 5,'BBB'] = -1; df
69+
df.loc[df.AAA >= 5,'BBB'] = -1; df
7070
7171
An if-then with assignment to 2 columns:
7272

7373
.. ipython:: python
7474
75-
df.ix[df.AAA >= 5,['BBB','CCC']] = 555; df
75+
df.loc[df.AAA >= 5,['BBB','CCC']] = 555; df
7676
7777
Add another line with different logic, to do the -else
7878

7979
.. ipython:: python
8080
81-
df.ix[df.AAA < 5,['BBB','CCC']] = 2000; df
81+
df.loc[df.AAA < 5,['BBB','CCC']] = 2000; df
8282
8383
Or use pandas where after you've set up a mask
8484

@@ -149,7 +149,7 @@ Building Criteria
149149
{'AAA' : [4,5,6,7], 'BBB' : [10,20,30,40],'CCC' : [100,50,-30,-50]}); df
150150
151151
aValue = 43.0
152-
df.ix[(df.CCC-aValue).abs().argsort()]
152+
df.loc[(df.CCC-aValue).abs().argsort()]
153153
154154
`Dynamically reduce a list of criteria using a binary operators
155155
<http://stackoverflow.com/questions/21058254/pandas-boolean-operation-in-a-python-list/21058331>`__
@@ -217,9 +217,9 @@ There are 2 explicit slicing methods, with a third general case
217217
218218
df.loc['bar':'kar'] #Label
219219
220-
#Generic
221-
df.ix[0:3] #Same as .iloc[0:3]
222-
df.ix['bar':'kar'] #Same as .loc['bar':'kar']
220+
# Generic
221+
df.iloc[0:3]
222+
df.loc['bar':'kar']
223223
224224
Ambiguity arises when an index consists of integers with a non-zero start or non-unit increment.
225225

@@ -231,9 +231,6 @@ Ambiguity arises when an index consists of integers with a non-zero start or non
231231
232232
df2.loc[1:3] #Label-oriented
233233
234-
df2.ix[1:3] #General, will mimic loc (label-oriented)
235-
df2.ix[0:3] #General, will mimic iloc (position-oriented), as loc[0:3] would raise a KeyError
236-
237234
`Using inverse operator (~) to take the complement of a mask
238235
<http://stackoverflow.com/questions/14986510/picking-out-elements-based-on-complement-of-indices-in-python-pandas>`__
239236

@@ -440,7 +437,7 @@ Fill forward a reversed timeseries
440437
.. ipython:: python
441438
442439
df = pd.DataFrame(np.random.randn(6,1), index=pd.date_range('2013-08-01', periods=6, freq='B'), columns=list('A'))
443-
df.ix[3,'A'] = np.nan
440+
df.loc[df.index[3], 'A'] = np.nan
444441
df
445442
df.reindex(df.index[::-1]).ffill()
446443
@@ -545,7 +542,7 @@ Unlike agg, apply's callable is passed a sub-DataFrame which gives you access to
545542
546543
agg_n_sort_order = code_groups[['data']].transform(sum).sort_values(by='data')
547544
548-
sorted_df = df.ix[agg_n_sort_order.index]
545+
sorted_df = df.loc[agg_n_sort_order.index]
549546
550547
sorted_df
551548

doc/source/gotchas.rst

+4-56
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ Label-based indexing with integer axis labels is a thorny topic. It has been
221221
discussed heavily on mailing lists and among various members of the scientific
222222
Python community. In pandas, our general viewpoint is that labels matter more
223223
than integer locations. Therefore, with an integer axis index *only*
224-
label-based indexing is possible with the standard tools like ``.ix``. The
224+
label-based indexing is possible with the standard tools like ``.loc``. The
225225
following code will generate exceptions:
226226

227227
.. code-block:: python
@@ -230,7 +230,7 @@ following code will generate exceptions:
230230
s[-1]
231231
df = pd.DataFrame(np.random.randn(5, 4))
232232
df
233-
df.ix[-2:]
233+
df.loc[-2:]
234234
235235
This deliberate decision was made to prevent ambiguities and subtle bugs (many
236236
users reported finding bugs when the API change was made to stop "falling back"
@@ -305,15 +305,15 @@ index can be somewhat complicated. For example, the following does not work:
305305

306306
::
307307

308-
s.ix['c':'e'+1]
308+
s.loc['c':'e'+1]
309309

310310
A very common use case is to limit a time series to start and end at two
311311
specific dates. To enable this, we made the design design to make label-based
312312
slicing include both endpoints:
313313

314314
.. ipython:: python
315315
316-
s.ix['c':'e']
316+
s.loc['c':'e']
317317
318318
This is most definitely a "practicality beats purity" sort of thing, but it is
319319
something to watch out for if you expect label-based slicing to behave exactly
@@ -322,58 +322,6 @@ in the way that standard Python integer slicing works.
322322
Miscellaneous indexing gotchas
323323
------------------------------
324324

325-
Reindex versus ix gotchas
326-
~~~~~~~~~~~~~~~~~~~~~~~~~
327-
328-
Many users will find themselves using the ``ix`` indexing capabilities as a
329-
concise means of selecting data from a pandas object:
330-
331-
.. ipython:: python
332-
333-
df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three', 'four'],
334-
index=list('abcdef'))
335-
df
336-
df.ix[['b', 'c', 'e']]
337-
338-
This is, of course, completely equivalent *in this case* to using the
339-
``reindex`` method:
340-
341-
.. ipython:: python
342-
343-
df.reindex(['b', 'c', 'e'])
344-
345-
Some might conclude that ``ix`` and ``reindex`` are 100% equivalent based on
346-
this. This is indeed true **except in the case of integer indexing**. For
347-
example, the above operation could alternately have been expressed as:
348-
349-
.. ipython:: python
350-
351-
df.ix[[1, 2, 4]]
352-
353-
If you pass ``[1, 2, 4]`` to ``reindex`` you will get another thing entirely:
354-
355-
.. ipython:: python
356-
357-
df.reindex([1, 2, 4])
358-
359-
So it's important to remember that ``reindex`` is **strict label indexing
360-
only**. This can lead to some potentially surprising results in pathological
361-
cases where an index contains, say, both integers and strings:
362-
363-
.. ipython:: python
364-
365-
s = pd.Series([1, 2, 3], index=['a', 0, 1])
366-
s
367-
s.ix[[0, 1]]
368-
s.reindex([0, 1])
369-
370-
Because the index in this case does not contain solely integers, ``ix`` falls
371-
back on integer indexing. By contrast, ``reindex`` only looks for the values
372-
passed in the index, thus finding the integers ``0`` and ``1``. While it would
373-
be possible to insert some logic to check whether a passed sequence is all
374-
contained in the index, that logic would exact a very high cost in large data
375-
sets.
376-
377325
Reindex potentially changes underlying Series dtype
378326
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
379327

0 commit comments

Comments
 (0)