Существует ли более эффективный способ извлечения строк со столбцом списка, который включает значения в списке? ( либо подмножество, объединение, либо надмножество )

#python #pandas #list #dataframe

Вопрос:

работа с фреймом pandas.dataframe, таким образом, чтобы:

 <class 'pandas.core.frame.DataFrame'>
Index: 685 entries, 7789285 to 8009947
Data columns (total 18 columns):
 #   Column            Non-Null Count  Dtype              
---  ------            --------------  -----              
 0   sourcedId         685 non-null    string             
 1   status            685 non-null    string             
 2   dateLastModified  685 non-null    datetime64[ns, UTC]
 3   username          685 non-null    string             
 4   userIds           685 non-null    object             
 5   enabledUser       685 non-null    string             
 6   givenName         685 non-null    string             
 7   familyName        685 non-null    string             
 8   middleName        685 non-null    string             
 9   role              685 non-null    string             
 10  identifier        685 non-null    string             
 11  email             685 non-null    string             
 12  sms               685 non-null    string             
 13  phone             685 non-null    string             
 14  agents            685 non-null    object             
 15  orgs              685 non-null    object             
 16  grades            685 non-null    object             
 17  password          685 non-null    string             
dtypes: datetime64[ns, UTC](1), object(4), string(13)
memory usage: 101.7  KB
df.head()
 

Столбец «оценки» содержит список целых чисел в виде строк, т. е., [‘9′,’10’]. Я могу фильтровать отдельные значения по

 mask = df.grades.apply(lambda x: '10' in x)
 

В моем тестовом наборе данных, который создается из списка списков, который я заполняю вручную, я использовал целочисленные значения, поэтому приведенное ниже работает просто отлично(?) ( предположим, для аргументации, что данные представляют собой список целых чисел, а не список строк )

 gradeList = [9,10]
mask = df.grades.apply(lambda x: any(map(lambda x,y: x==y,x gradeList)))
df[mask].head()
 

Я относительно новичок в Python ( за последние пять лет я накопил опыт работы на Python, который, по моему мнению, составляет от шести до восьми месяцев, если это так ) и совершенно новичок в Панд. У меня есть только приблизительное представление о понимании списка и функции карты.

Я предполагал, что вышесказанное позволит мне получить любые записи, для которых в столбце оценки присутствовало подмножество списка оценок. Для одного целого числа в классе это выполняется с помощью:

 mask = df.grades.apply(lambda x: grade in x)
 

Вместо того, чтобы достичь своей цели с помощью вышеупомянутых вложенных лямбд и карты, я создал нечто, в чем порядок терминов в параметрах запроса ( список оценок ) имеет важное значение. Ниже приведены выходные данные моего тестового сценария, который работает с тестовыми данными, включенными в выходные данные. Я стараюсь не принимать заказ ни для одного из списков…

 --------------------------------------------------------------------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 5 columns):
 #   Column     Non-Null Count  Dtype
---  ------     --------------  -----
 0   id         10 non-null     object
 1   email      10 non-null     object
 2   fullName   10 non-null     object
 3   jobTitles  10 non-null     object
 4   grades     10 non-null     object
dtypes: object(5)
memory usage: 528.0  bytes
--------------------------------------------------------------------------------
          id                 email          fullName                                          jobTitles           grades
0    smithsm    smithsm@aplace.com         Stu Smith  [developer, licensed pretend nurse, worthless ...  [9, 10, 11, 12]
1   mullenjb   mullenjb@aplace.com      Jason Mullen               [printer guy, supervisor, senior it]         [11, 12]
2    swainrl    swainrl@aplace.com        Ryan Swain                      [nap taker, goof-off, goober]          [9, 10]
3  rankinsns  rankinsns@aplace.com  Nicholas Rankins                           [manual tesla autopilot]          [9, 10]
4  carlsonrm  carlsonrm@aplace.com      Ryan Carlson                     [technician, snarky so-and-so]         [10, 11]
5     ragomv     ragomv@aplace.com         Mike Rago                                  [nice guy, swole]             [10]
6    smithdl    smithdl@aplace.com       David Smith                                         [old hand]              [9]
7  kappleraj  kappleraj@aplace.com   Allison Kappler      [girl coder, definitely not prettier than me]             [11]
8   iresonss   iresonss@aplace.com      Sandy Ireson                                      [hard worker]             [12]
9  conklincc  conklincc@aplace.com     Caleb Conklin                              [millenial magnum pi]          [12, 9]
--------------------------------------------------------------------------------
query for 'developer'
        id               email   fullName                                          jobTitles           grades
0  smithsm  smithsm@aplace.com  Stu Smith  [developer, licensed pretend nurse, worthless ...  [9, 10, 11, 12]
--------------------------------------------------------------------------------
query for 11
          id                 email         fullName                                          jobTitles           grades
0    smithsm    smithsm@aplace.com        Stu Smith  [developer, licensed pretend nurse, worthless ...  [9, 10, 11, 12]
1   mullenjb   mullenjb@aplace.com     Jason Mullen               [printer guy, supervisor, senior it]         [11, 12]
4  carlsonrm  carlsonrm@aplace.com     Ryan Carlson                     [technician, snarky so-and-so]         [10, 11]
7  kappleraj  kappleraj@aplace.com  Allison Kappler      [girl coder, definitely not prettier than me]             [11]
--------------------------------------------------------------------------------
query for 10
          id                 email          fullName                                          jobTitles           grades
0    smithsm    smithsm@aplace.com         Stu Smith  [developer, licensed pretend nurse, worthless ...  [9, 10, 11, 12]
2    swainrl    swainrl@aplace.com        Ryan Swain                      [nap taker, goof-off, goober]          [9, 10]
3  rankinsns  rankinsns@aplace.com  Nicholas Rankins                                       [technician]          [9, 10]
4  carlsonrm  carlsonrm@aplace.com      Ryan Carlson                     [technician, snarky so-and-so]         [10, 11]
5     ragomv     ragomv@aplace.com         Mike Rago                                  [nice guy, swole]             [10]
--------------------------------------------------------------------------------
query for 11,12
          id                 email         fullName                                      jobTitles    grades
1   mullenjb   mullenjb@aplace.com     Jason Mullen           [printer guy, supervisor, senior it]  [11, 12]
7  kappleraj  kappleraj@aplace.com  Allison Kappler  [girl coder, definitely not prettier than me]      [11]
--------------------------------------------------------------------------------
query for 10,11
          id                 email      fullName                       jobTitles    grades
4  carlsonrm  carlsonrm@aplace.com  Ryan Carlson  [technician, snarky so-and-so]  [10, 11]
5     ragomv     ragomv@aplace.com     Mike Rago               [nice guy, swole]      [10]
--------------------------------------------------------------------------------
query for 9,10
          id                 email          fullName                                          jobTitles           grades
0    smithsm    smithsm@aplace.com         Stu Smith  [developer, licensed pretend nurse, worthless ...  [9, 10, 11, 12]
2    swainrl    swainrl@aplace.com        Ryan Swain                      [nap taker, goof-off, goober]          [9, 10]
3  rankinsns  rankinsns@aplace.com  Nicholas Rankins                                       [technician]          [9, 10]
6    smithdl    smithdl@aplace.com       David Smith                                         [old hand]              [9]
--------------------------------------------------------------------------------
query for 10,9
          id                 email       fullName                       jobTitles    grades
4  carlsonrm  carlsonrm@aplace.com   Ryan Carlson  [technician, snarky so-and-so]  [10, 11]
5     ragomv     ragomv@aplace.com      Mike Rago               [nice guy, swole]      [10]
9  conklincc  conklincc@aplace.com  Caleb Conklin           [millenial magnum pi]   [12, 9]
 

Кто-нибудь может определить ( надеюсь, основную концепцию, которую я упускаю ) или указать мне на документацию, которая поможет мне разобраться в происходящем?

Ответ №1:

Я использовал более легкий фрейм данных:

 >>> df
          id           grades
0    smithsm     [1, 9, 2, 6]  # <- 9
1   mullenjb  [1, 5, 8, 4, 7]
2    swainrl        [4, 2, 9]  # <- 9
3  rankinsns           [5, 2]
4  carlsonrm  [7, 4, 6, 3, 2]  # <- 3
5     ragomv        [6, 1, 5]
6    smithdl  [2, 9, 6, 7, 3]  # <- 3 amp; 9
7  kappleraj        [9, 5, 8]  # <- 9
8   iresonss  [8, 6, 7, 5, 4]
9  conklincc           [8, 6]
 

Как найти список оценок [3, 9]?

Разверните свою колонку grades и найдите оценку в списке оценок.

 >>> df.loc[df['grades'].explode().isin([3, 9]).groupby(level=0).any()
          id           grades
0    smithsm     [1, 9, 2, 6]
2    swainrl        [4, 2, 9]
4  carlsonrm  [7, 4, 6, 3, 2]
6    smithdl  [2, 9, 6, 7, 3]
7  kappleraj        [9, 5, 8]
 

Так же, как:

>>>>>> df.loc[df['оценки'].взрыв() 
 .применить(лямбда x: x в [3, 9]) 
 .groupby(уровень=0).любой()]`

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

1. Это превосходно! Лучшее, что я смог сделать до сих пор, — это определить функцию, принимающую два списка в качестве параметров, вложив два цикла for в перечисление() для каждого списка, разделив итератор кортежа на индекс и значение, добавив результаты каждого теста на равенство во временный список, а затем возвращая любой() во временный список. Ваше решение намного, намного приятнее. Я прочитаю документацию о функции explode() и снова попытаюсь разобраться в параметре level

2. Рад, что чтение помогает. Не забудьте проголосовать и/или принять решение, если оно соответствует вашим потребностям.