Сопоставление значений нескольких столбцов с помощью 2 столбцов

#python #pandas

#python #pandas

Вопрос:

Пример DF:

 ID   Name     Match1    Random_Col    Match2    Price    Match3     Match4       Match5
1    Apple      Yes     Random Value   No        10      Yes        Yes          Yes
2    Apple      Yes     Random Value1  No        10      Yes        Yes          No
3    Apple      Yes     Random Value2  No        15      No         Yes          Yes
4    Orange     No      Random Value   Yes       12      Yes        Yes          No
5    Orange     No      Random Value   Yes       12      No         No           No
6    Banana     Yes     Random Value   No        15      Yes        No           No
7    Apple      Yes     Random Value   No        15      No        Yes          Yes
  

Ожидаемый DF:

 ID   Name     Match1    Random_Col    Match2  Price Match3  Match4 Match5 Final_Match
1    Apple      Yes     Random Value   No      10    Yes    Yes    Yes   Full
2    Apple      Yes     Random Value1  No      10    Yes    Yes    No  Partial
3    Apple      Yes     Random Value2  No      15    No     Yes    Yes Partial
4    Orange     No      Random Value   Yes     12    Yes    Yes    No    Full
5    Orange     No      Random Value   Yes     12    No     No     No Partial
6    Banana     Yes     Random Value   No      15    Yes    No     No   Full
7    Apple      Yes     Random Value   No      15    No     Yes    Yes Partial
  

Постановка задачи:

  1. Если комбинация Name и Price не повторяется, просто поместите Full в Final_Match столбец (пример ID 6)
  2. Если комбинация Name и Price повторяется, то внутри них подсчитывается количество Yes в столбцах Match1 -Match5, в зависимости от того, в каком из них больше «Да» Full для этого одного и Partial для другого (пример ID 1 amp; 2 и 4,5)

  3. Если комбинация Name и Price повторяется, то в пределах количества идентификаторов Yes в столбцах Match1 -Match5, если они имеют одинаковое значение «Да», ставится Partial в обоих (пример ID 3,7)

Код

 s = (df.replace({'Yes': 1, 'No': 0})
     .iloc[:, 1:]
     .sum(1))

df['final_match'] = np.where(s.groupby(df[['Price','Name']]).rank(ascending=False).eq(1), 'Full ','Partial')
  

Приведенный выше код работает, когда мне нужно было, groupby допустим, только по 1 столбцу Name , но он не работает для комбинации.

Любая помощь!!

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

1. Можете ли вы также предоставить код для воспроизведения вашего фрейма данных?

Ответ №1:

Используйте:

 #count Yes values only in Match columns
s = df.filter(like='Match').eq('Yes').sum(axis=1)
#mask for unique combinations
m1 = ~df.duplicated(['Price','Name'], keep=False)
#create new column filled by Series s
m2 = df.assign(new=s).groupby(['Price','Name'])['new'].rank(ascending=False).eq(1)
#chain masks by bitwise OR
df['final_match'] = np.where(m1 | m2, 'Full ','Partial')
print (df)

   ID    Name Match1     Random_Col Match2  Price Match3 Match4 Match5  
0   1   Apple    Yes   Random Value     No     10    Yes    Yes    Yes   
1   2   Apple    Yes  Random Value1     No     10    Yes    Yes     No   
2   3   Apple    Yes  Random Value2     No     15     No    Yes    Yes   
3   4  Orange     No   Random Value    Yes     12    Yes    Yes     No   
4   5  Orange     No   Random Value    Yes     12     No     No     No   
5   6  Banana    Yes   Random Value     No     15    Yes     No     No   
6   7   Apple    Yes   Random Value     No     15     No    Yes    Yes   

  final_match  
0       Full   
1     Partial  
2     Partial  
3       Full   
4     Partial  
5       Full   
6     Partial