#python #pandas #dataframe
Вопрос:
Я пытаюсь сделать что-то подобное. У меня есть фрейм данных:
list_val = {'Region': [3715, 3715, 3715, 3715, 3715, 3715, 3715, 3715, 3715, 3715, 3718, 3718, 3718], 'Category': [1, 1, 1, 1,1, 2, 2 ,2 ,2, 2,1 ,1 ,1], 'level': ['E', 'E/M', 'M', 'S', 'unknown', 'E', 'E/M', 'M', "S", "unknown", 'M', "E/M", 'unknown'], 'low': [2, 5, 10, 4, -1, 8, 12, 5, 14, -1, 3, 5, -1], 'high': [3, 6, 5, 6, -1, 12, 8, 9, 15, -1, 3, 8, -1]} df = pd.DataFrame(list_val) df
Region Category level low high 0 3715 1 E 2 3 1 3715 1 E/M 5 6 2 3715 1 M 10 5 3 3715 1 S 4 6 4 3715 1 unknown -1 -1 5 3715 2 E 8 12 6 3715 2 E/M 12 8 7 3715 2 M 5 9 8 3715 2 S 14 15 9 3715 2 unknown -1 -1 10 3718 1 M 3 3 11 3718 1 E/M 5 8 12 3718 1 unknown -1 -1
Я пытаюсь заполнить столбец «низкий» уровнем «неизвестный», т. е. -1 значением «низкий», где уровень «E», т. е. 2, и значением «высокий», с уровнем «неизвестный», т. е. -1 значением «высокий», где уровень «S», т. е. 6 и так далее для каждой категории и каждого региона. И если для любого региона и категории отсутствует уровень » E » или «S», сохраняйте низкое и высокое значение только как -1. Итак, чего я хочу, так это:
Region Category level low high 0 3715 1 E 2 3 1 3715 1 E/M 5 6 2 3715 1 M 10 5 3 3715 1 S 4 6 4 3715 1 unknown 2 6 5 3715 2 E 8 12 6 3715 2 E/M 12 8 7 3715 2 M 5 9 8 3715 2 S 14 15 9 3715 2 unknown 8 15 10 3718 1 M 3 3 11 3718 1 E/M 5 8 12 3718 1 unknown -1 -1
Я пробовал разные способы, но ничто не дает того, чего я хочу, последнее, что я пробовал, — это:
for index in df.index: if df.loc[index,'level'] == 'Unknown': df.loc[index,'low'] = df['low'].where(df['level'] == 'E') df.loc[index, 'high'] = df['high'].where(df['level] == 'S')
но это приводит к ошибкам. Не мог бы кто-нибудь, пожалуйста, подсказать, как мне это сделать? Спасибо!
Ответ №1:
Используйте loc
обновление с map/replace
:
e_val = df.loc[df['level']=='E'].set_index(['Region', 'Category'])['low'] # use `lower` since there is `unknown` and `Unknown` unknowns = df['level'].str.lower() == 'unknown' df.loc[unknowns, 'low'] = (df.loc[unknowns, ['Region','Category']] .agg(tuple,axis=1) .map(e_val) )
Выход:
Region Category level low high 0 3715 1 E 2.0 3 1 3715 1 E/M 5.0 6 2 3715 1 M 10.0 5 3 3715 1 S 4.0 6 4 3715 1 unknown 2.0 -1 5 3715 2 E 8.0 12 6 3715 2 E/M 12.0 8 7 3715 2 M 5.0 9 8 3715 2 S 14.0 15 9 3715 2 unknown 8.0 -1 10 3718 1 M 3.0 3 11 3718 1 E/M 5.0 8 12 3718 1 unknown NaN -1
Комментарии:
1. Привет, Куанг, большое тебе спасибо. У меня есть следующий вопрос, что делать, если у нас много регионов, таких как 3715, 3718,….. и т.д., И в каждом регионе много категорий, как здесь, в регионе 3715 есть категории 1 и 2. и мы хотим рассчитать одно и то же для каждого региона, каждой категории. Какие изменения я должен внести? Я добавил регион в строке 1:
e_val = df.loc[df['level']=='E'].set_index('Region', 'Category')['low']
как соответствующим образом изменить последнюю строку?2. Привет, Куанг, я обновил свой вопрос для большей ясности!
3. Перед этим вам необходимо объединить пары ключей в кортежи
map
. см.Отредактированный ответ.4. Спасибо тонне Куанг. Работает отлично!