Панды выбирают соответствие нескольким столбцам

#pandas #multi-index

Вопрос:

У меня есть такие данные:

 category = ['Car','Car','Car','Car','Truck','Truck','Truck'] name = ['Camry','Camry','Camry','Camry','Tacoma','Tundra','Tundra'] year = ['2007','2007','2008','2009','2010','2010','2011'] vals = [0.1,0.5,0.2,0.9,0.8,0.4,0.9] df = pd.DataFrame({'Category': category,  'Name': name,  'Year': year,  'Vals': vals})  
Указатель Категория Имя Год Валс
0 Автомобиль Camry 2007 0.1
1 Автомобиль Camry 2007 0.5
2 Автомобиль Camry 2008 0.2
3 Автомобиль Camry 2009 0.9
4 Грузовик Такома 2010 0.8
5 Грузовик Тундра 2010 0.4
6 Грузовик Тундра 2011 0.9

Затем у меня есть набор комбинаций (Категория, Имя, Год), для которых я хочу отфильтровать фрейм данных. Они могут быть в любом формате, но здесь они находятся во фрейме данных.

 combinations_i_want = pd.DataFrame() # (Car, Camry, 2007) combinations_i_want = combinations_i_want.append({'Category':'Car', 'Name':'Camry','Year':'2007'},ignore_index=True) # 2 matches in df # (Truck, Tundra, 2010) combinations_i_want = combinations_i_want.append({'Category':'Truck', 'Name':'Tundra','Year':'2010'},ignore_index=True) # 1 match in df  

Я хочу извлечь строки в df, которые точно соответствуют этим двум комбинациям. Это будут строки 0, 1 и 5. Результирующая таблица будет выглядеть следующим образом:

Указатель Категория Имя Год Валс
0 Автомобиль Camry 2007 0.1
1 Автомобиль Camry 2007 0.5
5 Грузовик Тундра 2010 0.4

Примечание: Мне не нужны старые индексы, они просто помогают визуализировать.

Как мне это сделать?

Ответ №1:

Вы можете просто присоединиться к столбцам, которые вы хотите.

 result = df.merge(combinations_i_want, how='right', on=['Category', 'Name', 'Year'])  

Ответ №2:

Вы должны использовать .loc и .isin вместо .append

Ваше предложение может быть примерно таким:

 df.loc[(df['Category'].isin(['Car', 'Truck'])) amp; (df['Name'].isin(['Camry', 'Tundra'])) amp; (df['Year'].isin(['2007', '2010']))]  

Это должно дать результаты, которых вы ожидаете.

Вы можете назначить его переменной, если хотите, например

 combinations_i_want = df.loc[(df['Category'].isin(['Car', 'Truck'])) amp;  (df['Name'].isin(['Camry', 'Tundra'])) amp;  (df['Year'].isin(['2007', '2010']))]   print(combinations_i_want)  

Комментарии:

1. В моих реальных данных может быть гипотетическое (Автомобиль, Тундра, 2010) значение, означающее, что мне нужно, чтобы каждый столбец идеально совпадал.

2. Я полагаю, что OP имел в виду, что им нужны строки, которые точно соответствуют строке комбинации, указанной ими ранее, что в основном является соединением sql.

3. @rdk тогда вы могли бы использовать | вместо amp; того, чтобы оставлять открытым вариант быть тем или иным.

Ответ №3:

используйте запрос фрейма данных, он даст вам идеальное совпадение на основе логической логики

 print(df.query("(Category=='Car' and Name=='Camry' and Year=='2007') or (Category=='Truck' and Name=='Tundra' and Year=='2010')"))  

выход:

 Category Name Year Vals  0 Car Camry 2007 0.1  1 Car Camry 2007 0.5  5 Truck Tundra 2010 0.4