Фильтрация данных, выполняющих поиск с разделенными запятыми значениями

#python #pandas #lambda #filter #slice

#python #pandas #лямбда #Фильтр #срез

Вопрос:

У меня есть следующий фрейм данных, который представляет номер сотрудника, отдел, в котором они находятся, и код их роли в компании, который может быть «1» или «2». В столбце «Название отдела» у вас может быть либо отдел, в котором сотрудник имеет свою роль (соглашение об именовании «XX: название отдела», где XX — код страны), либо, в некоторых случаях, появляется группа отделов, разделенных запятой «,» с ролью, которую имеет сотрудникв этих отделах. Это будет выглядеть примерно так:

   Department Name                Employee Number      Role Code   
0  AU:Dept1                         1000                     1
1  AU:Dept1, AU:Dept3               1000                     2
2  AU:Dept7                         1000                     1
3  CZ:Dept3                         1001                     2
4  CZ:Dept4, CZ:Dept6, CZ:Dept7     1001                     2
5  CZ:Dept4                         1001                     1 
6  PL:Dept1                         1002                     2
7  PL:Dept2, PL:Dept1               1002                     1
8  PL:Dept3                         1002                     2
9  SG:Dept1                         1003                     1
10 SG:Dept1                         1003                     2
11 SG:Dept2                         1003                     2
  

Сотрудники могут иметь либо только роль 1, либо роль 2 в каждом уникальном названии отдела, поэтому мне нужно создать код, который возвращал бы все конфликтующие строки, в которых сотрудник, по-видимому, имеет как роль 1, так и роль 2 в одном и том же отделе. Это будет результат:

   Department Name                Employee Number      Role Code   
0  AU:Dept1                         1000                     1
1  AU:Dept1, AU:Dept3               1000                     2
4  CZ:Dept4, CZ:Dept6, CZ:Dept7     1001                     2
5  CZ:Dept4                         1001                     1 
6  PL:Dept1                         1002                     2
7  PL:Dept2, PL:Dept1               1002                     1
9  SG:Dept1                         1003                     1
10 SG:Dept1                         1003                     2
  

Каков наилучший способ выполнить этот фильтр?

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

1. Вы пробовали это? Почтовый индекс. Мы можем помочь с конкретными проблемами в вашем коде.

2. Извините, я был в отпуске, уже принял ответ, спасибо!

Ответ №1:

Вы можете сделать что-то вроде

 df['both_role'] = df.groupby('Employee Number')['Role Code'].isin([1]).astype(int) * df.groupby('Employee Number')['Role Code'].isin([2]).astype(int) 

df[df.both_role == 1]
  

Вы можете сгруппироваться, используя номер сотрудника, и проверить, содержит ли код роли 1 и 2 для каждого пользователя. Если он содержит как 1, так и 2, вы можете фильтровать фрейм данных.

Ответ №2:

Давайте попробуем разделить название отдела, а затем groupby ['Employee', 'Name'] выяснить, какие сотрудники имеют две роли с nunique :

 (df.assign(Name=df['Department Name'].str.split(', '))
   .explode('Name')
   .loc[lambda x:x.groupby(['Employee Number','Name'])
                 ['Role Code'].transform('nunique') ==2 ]
   .drop('Name', axis=1)
)
  

Вывод:

                  Department Name  Employee Number  Role Code
0                       AU:Dept1             1000          1
1             AU:Dept1, AU:Dept3             1000          2
4   CZ:Dept4, CZ:Dept6, CZ:Dept7             1001          2
5                       CZ:Dept4             1001          1
6                       PL:Dept1             1002          2
7             PL:Dept2, PL:Dept1             1002          1
9                       SG:Dept1             1003          1
10                      SG:Dept1             1003          2