#python #pandas
#python #pandas
Вопрос:
Пример DF:
ID Name Price Condition Fit_Test
1 Apple 10 Good Super_Fit
2 Apple 10 OK Super_Fit
3 Apple 10 Bad Super_Fit
4 Orange 12 Good Not_Fit
5 Orange 12 OK Not_Fit
6 Banana 15 OK Medium_Fit
7 Banana 15 Bad Medium_Fit
8 Pineapple 25 OK Medium_Fit
9 Pineapple 25 OK Medium_Fit
10 Cherry 30 Bad Medium_Fit
Ожидаемый DF:
ID Name Price Condition Fit_Test
1 Apple 10 Good Super_Fit
2 Apple 10 OK Super_Fit
3 Apple 10 Bad Super_Fit
4 Orange 12 Good Not_Fit
6 Banana 15 OK Medium_Fit
8 Pineapple 25 OK Medium_Fit
9 Pineapple 25 OK Medium_Fit
10 Cherry 30 Bad Medium_Fit
Постановка задачи:
Я хочу group-by
по Name
и Price
, а затем фильтровать на основе Condition
.
-
Если в пределах
Name
иPrice
существуют все 3 условия Good, Bad и OK, тогда сохраняйте только Good, а Fit_Test — нетSuper_Fit
-
Если в пределах названия и цены существуют условия Good и OK, тогда оставьте только Good one (Id 4,5 — это только ожидаемый ID 4), а Fit_Test — нет
Super_Fit
-
Если в пределах
Name
иPrice
существуют условия Bad и OK, тогда оставьте только один OK (идентификатор 6,7 — это только ожидаемый идентификатор 6), а Fit_Test — нетSuper_Fit
-
Если в пределах
Name
иPrice
существуют условия OK и OK, существуют Good и Good или просто Bad, тогда ничего не делайте, тогда оставьте только OK one (Id 8,9,10 — это ожидаемый идентификатор 8,9,10), а Fit_Test — нетSuper_Fit
Обновление ответов
- Первый ответ и редактирование для тестирования работает для всех,
df
где у вас нет условия дляFit_Test
столбца. В этом ответе ожидаемый DF не будет иметь строк 2 и 3, как также показано в ответе - Ответ Редактировать для обновления работает, когда вам нужно взять другие столбцы, которые есть
Fit_Test
и должны работать только тогда, когда значение не являетсяSuper_Fit
.
В обоих решениях фильтрация строк на основе Condition
столбца и группировка по 2 столбцам одинаковы.
Я нашел вещи с filter group by в числовых столбцах, но ничего не нашел в строковых столбцах.
Ответ №1:
Идея в том, чтобы создать set
ы для сравнения:
a = df.join(df.groupby(['Price','Name'])['Condition'].apply(set).rename('m'),
on=['Price','Name'])['m']
print (a)
0 {Bad, Good, OK}
1 {Bad, Good, OK}
2 {Bad, Good, OK}
3 {Good, OK}
4 {Good, OK}
5 {Bad, OK}
6 {Bad, OK}
7 {OK}
8 {OK}
9 {Bad}
Name: m, dtype: object
m1 = (a == set({'Bad', 'Good', 'OK'})) | (a == set({'Good', 'OK'}))
m2 = a == set({'Bad', 'OK'})
#check if unique value - length of set is 1
m3 = a.str.len() == 1
m4 = df['Condition'] == 'Good'
m5 = df['Condition'] == 'OK'
df = df[(m1 amp; m4) | (m2 amp; m5) | m3]
print (df)
ID Name Price Condition
0 1 Apple 10 Good
3 4 Orange 12 Good
5 6 Banana 15 OK
7 8 Pineapple 25 OK
8 9 Pineapple 25 OK
9 10 Cherry 30 Bad
РЕДАКТИРОВАТЬ для тестирования:
Для тестирования возможно использование assign
:
print (df.assign(sets=a, m1 = m1, m2=m2, m3=m3, m4=m4, m5=m5, m=m))
ID Name Price Condition sets m1 m2 m3
0 1 Apple 10 Good {Bad, Good, OK} True False False
1 2 Apple 10 OK {Bad, Good, OK} True False False
2 3 Apple 10 Bad {Bad, Good, OK} True False False
3 4 Orange 12 Good {Good, OK} True False False
4 5 Orange 12 OK {Good, OK} True False False
5 6 Banana 15 OK {Bad, OK} False True False
6 7 Banana 15 Bad {Bad, OK} False True False
7 8 Pineapple 25 OK {OK} False False True
8 9 Pineapple 25 OK {OK} False False True
9 10 Cherry 30 Bad {Bad} False False True
m4 m5 m
0 True False True
1 False True False
2 False False False
3 True False True
4 False True False
5 False True True
6 False False False
7 False True True
8 False True True
9 False False True
РЕДАКТИРОВАТЬ для обновления:
Для нового условия используйте:
m6 = df['Fit_Test'] == 'Super_Fit'
df = df[((m1 amp; m4) | (m2 amp; m5) | m3) | m6]
print (df)
ID Name Price Condition Fit_Test
0 1 Apple 10 Good Super_Fit
1 2 Apple 10 OK Super_Fit
2 3 Apple 10 Bad Super_Fit
3 4 Orange 12 Good Not_Fit
5 6 Banana 15 OK Medium_Fit
7 8 Pineapple 25 OK Medium_Fit
8 9 Pineapple 25 OK Medium_Fit
9 10 Cherry 30 Bad Medium_Fit
Комментарии:
1. Будет ли это также учитывать
Good Good
условие2. @RahulAgarwal — да, потому что set create
{Good}
иm3
являетсяTrue
3. Я теряю строки, где у меня есть только один
OK
. Я вижу, чтоa
это правильно, но вdf
я вижу, что этих строк там нет.4. @RahulAgarwal — значит, в
a
есть только{OK}
? И эти строки удалены?5. @RahulAgarwal — Спасибо.
Ответ №2:
Если у вас не слишком много условий (например, здесь всего 3), ниже приведен простой обходной путь:
df.loc[df["Condition"] == 'Good',"Condition"] = 3
df.loc[df["Condition"] == 'OK',"Condition"] = 2
df.loc[df["Condition"] == 'Bad',"Condition"] = 1
df = df.groupby(['Name','Price']).max()
df.loc[df["Condition"] == 3] = "Good"
df.loc[df["Condition"] == 2] = "OK"
df.loc[df["Condition"] == 1] = "Bad"
Комментарии:
1. Это удаление строк, в которых у меня есть
Good Good
условие?2. Да, если все хорошо, тогда я хочу сохранить их все. Пункт 4 в моем вопросе!!
3. ОК. Прежде всего, нет причин расстраиваться.
4. Если это кажется таким, я приношу извинения. Я не расстроен или что-то в этом роде. Прежде всего, вы помогаете мне!!