Это вопрос о том, как все сделать правильно с pandas (я использую версию 1.0
). Допустим, у меня есть DataFrame с миссиями, который содержит источник и одно или несколько мест назначения:
mid from to
0 0 A [C]
1 1 A [B, C]
2 2 B [B]
3 3 C [D, E, F]
Например: для миссии (mid=1
) люди будут путешествовать от A
до B
, затем от B
до C
и, наконец, от C
до A
. Обратите внимание, что я не контролирую модель данных входного фрейма данных.
Я хотел бы вычислять метрики для каждой поездки миссии. Ожидаемый результат будет точно:
tid mid from to
0 0 0 A C
1 1 0 C A
2 2 1 A B
3 3 1 B C
4 4 1 C A
5 5 2 B B
6 6 2 B B
7 7 3 C D
8 8 3 D E
9 9 3 E F
10 10 3 F C
Я нашел способ достичь своей цели. Пожалуйста, найдите ниже MCVE:
import pandas as pd
# Input:
df = pd.DataFrame(
[["A", ["C"]],
["A", ["B", "C"]],
["B", ["B"]],
["C", ["D", "E", "F"]]],
columns = ["from", "to"]
).reset_index().rename(columns={'index': 'mid'})
# Create chain:
df['chain'] = df.apply(lambda x: list(x['from']) + x['to'] + list(x['from']), axis=1)
# Explode chain:
df = df.explode('chain')
# Shift to create travel:
df['end'] = df.groupby("mid")["chain"].shift(-1)
# Remove extra row, clean, reindex and rename:
df = df.dropna(subset=['end']).reset_index(drop=True).reset_index().rename(columns={'index': 'tid'})
df = df.drop(['from', 'to'], axis=1).rename(columns={'chain': 'from', 'end': 'to'})
Мой вопрос: Есть ли лучший / более простой способ сделать это с Pandas? Говоря лучше, я имею в виду, не нужно больше производительный (это может быть конечно), но более читаемый и интуитивно понятный.