#python #pandas
Вопрос:
Рассмотрим этот простой фрейм данных pandas со столбцами «запись», «начало» и «параметры». Может быть несколько строк с одним и тем же значением записи, и каждое уникальное значение записи соответствует одному и тому же начальному значению. Однако значение «параметр» может отличаться для одной и той же комбинации «запись» и «начало»:
pd.DataFrame({'record':[1,2,3,4,4,5,6,7,7,7,8], 'start':[0,5,7,13,13,19,27,38,38,38,54], 'param':['t','t','t','u','v','t','t','t','u','v','t']})
Я хотел бы создать столбец «конец», который принимает значение «начало» в строке со следующим уникальным значением «запись». Значения столбца «конец» должны быть:
[5,7,13,19,19,27,38,54,54,54,NaN]
Я могу сделать это с помощью цикла for, но я знаю, что это не предпочтительно при использовании панд:
max_end = 100 for idx, row in df.iterrows(): try: n = 1 next_row = df.iloc[idx n] while next_row['start'] == row['start']: n = n 1 next_row = df.iloc[idx n] end = next_row['start'] except: end = max_end df.at[idx, 'end'] = end
Есть ли простой способ добиться этого без цикла for?
Комментарии:
1. Я верю, что ты что-то пробовал, верно? Пожалуйста, предоставьте свою попытку здесь, и не могли бы вы немного объяснить, как был создан этот конечный столбец(Условия….)?
Ответ №1:
Я не сомневаюсь, что есть более разумное решение, но вот мое.
df1['end'] = df1.drop_duplicates(subset = ['record', 'start'])['start'].shift(-1).reindex(index = df1.index, method = 'ffill')
-=РЕДАКТИРОВАТЬ=- Добавлено подмножество drop_duplicates
для учета поправки к вопросу
Комментарии:
1. Это сработало для примера, который я опубликовал. Я понял, что должен был предоставить более подробный пример того, что я делаю, потому что это не работает при использовании моего реального фрейма данных. Я обновил вопрос, чтобы отразить это!
2. Попробуйте сейчас, должно быть только удаление дубликатов среди этих столбцов
Ответ №2:
Это решение эквивалентно @Quixotic22, хотя и более явное.
df = pd.DataFrame({ 'record':[1,2,3,4,4,5,6,7,7,7,8], 'start':[0,5,7,13,13,19,27,38,38,38,54], 'param':['t','t','t','u','v','t','t','t','u','v','t'] }) max_end = 100 df["end"] = None # create new column with empty values loc = df["record"].shift(1) != df["record"] # record where the next value is diff from previous df.loc[loc, "end"] = df.loc[loc, "start"].shift(-1) # assign desired values df["end"].fillna(method = "ffill", inplace = True) # fill remaining missing values df.loc[df.index[-1], "end"] = max_end # override last value df