#python #pandas
#python #pandas
Вопрос:
Пример DF:
ID Name Price Sum
1 Apple 10 180
2 Apple 10 100
3 Apple 10 80
4 Orange 12 180
5 Orange 12 190
6 Banana 15 50
7 Banana 15 30
Ожидаемый DF:
ID Name Price Sum Result
1 Apple 10 180 Full Match
2 Orange 12 180 Match - High Confidence
3 Orange 12 190 Match - High Confidence
4 Banana 15 50 Match - Low Confidence
5 Banana 15 30 Match - Low Confidence
Постановка задачи:
Мне нужны Result
столбцы, которые работают при следующих условиях:
-
Для группы
Name
иPrice
, т.е. Название — Apple, а цена — 10, если наибольшее значение не находится в диапазоне — 30 для других, тогда сохраните строку с наибольшим значением со столбцом результата какFull Match
и удалите другие (пример Df — ID 1,2,3, а ожидаемый DF — только идентификатор 1) -
Внутри группы
Name
иPrice
если она находится в диапазоне — 30, а также больше 100, то столбцы результатов будутMatch - High Confidence
, и никакие строки не будут удалены (пример Df — ID 4,5, а ожидаемый DF — ID 2,3) -
Внутри группы
Name
иPrice
если она находится в диапазоне — 30 и меньше 60, то столбцы результатов будутMatch - Low Confidence
, и никакие строки не будут удалены (примерный Df — ID 6,7, а ожидаемый DF — ID 4,5)
Я не могу найти ничего о том, как решить эту проблему, когда задействована комбинация групп плюс диапазон. Любая помощь?
Комментарии:
1. @jezrael: Любая помощь здесь!!!
2. Извините, меня здесь не было, время обеда 😉
Ответ №1:
Вот что я придумал, вы можете попробовать:
#get absolute difference from max value
df['diff_abs']=abs(df.Sum-df.groupby(['Name','Price'])['Sum'].transform('max'))
#check if diff less than 30 remove them
m=df.loc[df.duplicated(['Name','Price'],keep=False)amp;df.diff_abs.lt(30)].reset_index()
print(m)
index ID Name Price Sum diff_abs
0 0 1 Apple 10 180 0
1 3 4 Orange 12 180 10
2 4 5 Orange 12 190 0
3 5 6 Banana 15 50 0
4 6 7 Banana 15 30 20
c1=~m.duplicated(['Name','Price'],keep=False) #check if entry is just 1 and no dups
c2=m.duplicated(['Name','Price'],keep=False)amp;m.Sum.lt(60) #if dups check for less than 60
m['result']=np.select([c1,c2],
['Full Match','Match - Low Confidence'],'Match - High Confidence')
print(m)
index ID Name Price Sum diff_abs result
0 0 1 Apple 10 180 0 Full Match
1 3 4 Orange 12 180 10 Match - High Confidence
2 4 5 Orange 12 190 0 Match - High Confidence
3 5 6 Banana 15 50 0 Match - Low Confidence
4 6 7 Banana 15 30 20 Match - Low Confidence
Комментарии:
1. Получение этой ошибки
TypeError: unsupported operand type(s) for -: 'method' and 'int'
вdf['diff_abs']=abs(df.Sum-df.groupby(['Name','Price'])['Sum'].transform('max'))
строке2. Это
minus
операция, которая выдает эту ошибку3. @RahulAgarwal я думаю, что проблема, связанная с данными, работает для примера, есть ли пробелы в столбцах, если да,
-
не работает. вы можете проверить их, иначе @jez-offer будет лучшим. 🙂 !!4. На самом деле я заменил
df.sum
наdf["sum"]
, и это сработало 🙂5. @RahulAgarwal да, это потому, что
sum
это метод, вам следует избегать использования методов в качестве переменных. 🙂 Я думал, что имя столбцаSum
, рад, что это сработало
Ответ №2:
Я думаю, вам нужно:
#get Series for maximal value of group
maxpergroup = df.groupby(['Name','Price'])['Sum'].transform('max')
#subtract values, get absolute values and compare by greater 30
m1 = df['Sum'].sub(maxpergroup).abs().gt(30)
#get all groups where at least one True
m11 = m1.groupby([df['Name'],df['Price']]).transform('any')
#print (m11)
#compare by another values and test if all values matching per groups
m2 = df['Sum'].gt(100)
m22 = (m2 amp; ~m1).groupby([df['Name'],df['Price']]).transform('all')
#print (m22)
m3 = df['Sum'].lt(60)
m33 = (m3 amp; ~m1).groupby([df['Name'],df['Price']]).transform('all')
#print (m33)
#create new column
masks = [m11,m22, m33]
vals = ['Full Match','Match - Low Confidence','Match - High Confidence']
df['result'] = np.select(masks, vals)
#remove unnecessary rows
df = df[~m11 | df['Sum'].eq(maxpergroup)]
print (df)
ID Name Price Sum result
0 1 Apple 10 180 Full Match
3 4 Orange 12 180 Match - Low Confidence
4 5 Orange 12 190 Match - Low Confidence
5 6 Banana 15 50 Match - High Confidence
6 7 Banana 15 30 Match - High Confidence
Комментарии:
1. Я получаю эту ошибку
ValueError: invalid entry 0 in condlist: should be boolean ndarray
в этой строкеdf['result'] = np.select(masks, vals)
2. @RahulAgarwal — Похоже, ошибка, связанная с данными, являются ли данные конфиденциальными?
3. Не так много.. Я могу маскировать!!
4. @RahulAgarwal — Таким образом, вы можете поделиться ссылкой на данные через dropbox, gdocs или аналогичные или отправить данные на мою электронную почту из моего профиля.
5. @anky_91 — Спасибо, я проверяю ваше решение и, кажется, вы проверяете значения по группам? Кажется, нет.