Как сбросить индекс в целочисленные значения с Multiindex? - PullRequest
0 голосов
/ 04 апреля 2020

При работе с одноиндексированным DataFrame я склонен использовать reset_index(), чтобы переключить индекс обратно на целочисленные значения.

Однако при использовании мультииндексов он полностью понижает уровень. Сброс к целочисленным значениям не работает.

import pandas as pd
from random import seed, randint
from collections import OrderedDict

p1h = pd.period_range(start='2020-02-01 00:00', end='2020-02-02 00:00', freq='1h', name='p1h')
seed(1)
values1 = [randint(0,10) for p in p1h]
seed(2)
values2 = [randint(0,10) for p in p1h]

df1 = pd.DataFrame({'Values1' : values1, 'Values2' : values2}, index=p1h)

df2 = df1.stack()

Результат:

df2.head(6)

p1h                      
2020-02-01 00:00  Values1    2
                  Values2    0
2020-02-01 01:00  Values1    9
                  Values2    1
2020-02-01 02:00  Values1    1
                  Values2    1

df2.reset_index(level=1, drop=True).head(6)

p1h
2020-02-01 00:00    2
2020-02-01 00:00    0
2020-02-01 01:00    9
2020-02-01 01:00    1
2020-02-01 02:00    1
2020-02-01 02:00    1

Мне нужно, чтобы целочисленные значения перезапускались до 0 в каждой новой группе, определенной уровнем индекса 0.

                     Values   
Timestamp                      
2020-02-01 00:00  0       2
                  1       0
2020-02-01 01:00  0       9
                  1       1
2020-02-01 02:00  0       1
                  1       1   

Пожалуйста, есть у кого-нибудь идеи? Спасибо за вашу помощь! Bests,

1 Ответ

1 голос
/ 04 апреля 2020

Я думаю, что проще всего здесь установить имена столбцов на range, поэтому, если использовать stack, получите счетчик:

df1 = pd.DataFrame({'Values1' : values1, 'Values2' : values2}, index=p1h)

df1.columns = range(len(df1.columns))
df2 = df1.stack()
print (df2.head(6))
p1h                
2020-02-01 00:00  0    2
                  1    0
2020-02-01 01:00  0    9
                  1    1
2020-02-01 02:00  0    1
                  1    1
dtype: int64

При работе с MultiIndex одна идея - использовать rename:

d = {'Values1':0, 'Values2':1}
df2 = df1.stack().rename(d, level=1)
print (df2.head(6))
p1h                
2020-02-01 00:00  0    2
                  1    0
2020-02-01 01:00  0    9
                  1    1
2020-02-01 02:00  0    1
                  1    1
dtype: int64

Или назначить счетчик с помощью GroupBy.cumcount:

df2 = (df2.reset_index(level=1, drop=True)
          .to_frame()
          .set_index(df2.groupby(level=0).cumcount(), append=True)[0])

print (df2.head(6))
p1h                
2020-02-01 00:00  0    2
                  1    0
2020-02-01 01:00  0    9
                  1    1
2020-02-01 02:00  0    1
                  1    1
Name: 0, dtype: int64
...