How to slice a dataframe with multi index by row number (which is not in index) without destroying the index?

Viewed 349

Pandas 1.1.4

import pandas as pd
import numpy as np

mux = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    list('tuvwtuvwtuvwtuvw')
], names=['one', 'two'])

df = pd.DataFrame({'col': np.arange(len(mux))}, mux)
df["col2"] = 5    

print(df)
         col  col2
one two           
a   t      0     5
    u      1     5
    v      2     5
    w      3     5
b   t      4     5
    u      5     5
    v      6     5
    w      7     5
    t      8     5
c   u      9     5
    v     10     5
d   w     11     5
    t     12     5
    u     13     5
    v     14     5
    w     15     5

Now

df.loc[2:10, "col"] = 999

gives the expected result

one two           
a   t      0     5
    u      1     5
    v    999     5
    w    999     5
b   t    999     5
    u    999     5
    v    999     5
    w    999     5
    t    999     5
c   u    999     5
    v     10     5
d   w     11     5
    t     12     5
    u     13     5
    v     14     5
    w     15     5

but warns

FutureWarning: Slicing a positional slice with .loc is not supported, and will raise TypeError in a future version. Use .loc with labels or .iloc with positions instead. df.loc[2:10, "col"] = 999


Doing

df["col"].iloc[2:10] = 999

gives another (worse) warning:

SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy iloc._setitem_with_indexer(indexer, value)


How to do this correctly, while keeping the index?

I couldn't find this use case here

0 Answers
Related