Панды: перечислять дубликаты в индексе - PullRequest
0 голосов
/ 16 ноября 2018

Допустим, у меня есть список событий, которые происходят на разных клавишах.

data = [
    {"key": "A", "event": "created"},
    {"key": "A", "event": "updated"},
    {"key": "A", "event": "updated"},
    {"key": "A", "event": "updated"},
    {"key": "B", "event": "created"},
    {"key": "B", "event": "updated"},
    {"key": "B", "event": "updated"},
    {"key": "C", "event": "created"},
    {"key": "C", "event": "updated"},
    {"key": "C", "event": "updated"},
    {"key": "C", "event": "updated"},
    {"key": "C", "event": "updated"},
    {"key": "C", "event": "updated"},
]

df = pandas.DataFrame(data)

Я хотел бы сначала проиндексировать мой DataFrame по ключу, а затем перечисление. Это похоже на простую операцию unstack, но я не могу найти, как это сделать правильно.

Лучшее, что я мог сделать, это

df.set_index("key", append=True).swaplevel(0, 1)

          event
key            
A   0   created
    1   updated
    2   updated
    3   updated
B   4   created
    5   updated
    6   updated
C   7   created
    8   updated
    9   updated
    10  updated
    11  updated
    12  updated

но я ожидаю, что

          event
key            
A   0   created
    1   updated
    2   updated
    3   updated
B   0   created
    1   updated
    2   updated
C   0   created
    1   updated
    2   updated
    3   updated
    4   updated
    5   updated

Я тоже пробовал что-то вроде

df.groupby("key")["key"].count().apply(range).apply(pandas.Series).stack()

но порядок не сохраняется, поэтому я не могу применить результат в качестве индекса. Кроме того, я чувствую, что это излишне для операции, которая выглядит вполне стандартной ...

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Вы можете сделать это в numpy, как это:

# df like in OP
keys = df['key'].values
# detect indices where key changes value
change = np.zeros(keys.size, dtype=int)
change[1:] = keys[1:] != keys[:-1]
# naive sequential number
seq = np.arange(keys.size)
# offset by seq at most recent change
offset = np.maximum.accumulate(change * seq)
df['seq'] = seq - offset
print(df.set_index(['key', 'seq']))

           event
key seq         
A   0    created
    1    updated
    2    updated
    3    updated
B   0    created
    1    updated
    2    updated
C   0    created
    1    updated
    2    updated
    3    updated
    4    updated
    5    updated
0 голосов
/ 16 ноября 2018

groupby + cumcount

Вот несколько способов:

# new version thanks @ScottBoston
df = df.set_index(['key', df.groupby('key').cumcount()])\
       .rename_axis(['key','count'])

# original version
df = df.assign(count=df.groupby('key').cumcount())\
       .set_index(['key', 'count'])

print(df)

             event
key count         
A   0      created
    1      updated
    2      updated
    3      updated
B   0      created
    1      updated
    2      updated
C   0      created
    1      updated
    2      updated
    3      updated
    4      updated
    5      updated
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...