использование isin () для столбца, который имеет значения списка - PullRequest
1 голос
/ 15 июня 2019

У меня есть два кадра данных. Кадр данных A имеет столбец, который состоит из list значений идентификаторов (именованных элементов). Кадр данных B содержит столбец int значений идентификаторов (с именем id).

Dataframe A:

date       |    items
2019-06-05 | [121, 123, 124]
2019-06-06 | [109, 125]
2019-06-07 | [108, 126]

кадр данных B:

name  | id
item1 | 121
item2 | 122
item3 | 123
item4 | 124
item5 | 125
item6 | 126

Я хочу отфильтровать Dataframe A и сохранить только те строки, в которых все значения items в этой строке существуют в столбце id Dataframe B.

Исходя из приведенного выше примера, результат должен быть:

кадр данных C:

date       |    items
2019-06-05 | [121, 123, 124]

(поскольку в Dataframe B нет строк с id == 108 и id == 109)

Если бы items был столбцом int, я мог бы использовать:

dataframe_a[dataframe_a.items.isin(dataframe_b.id)]

Как мне добиться этого в list столбцах?

Ответы [ 3 ]

3 голосов
/ 15 июня 2019

Мы можем использовать issubset

l=[set(x).issubset(dfb.id.tolist())for x in df['items']]
Out[64]: [True, False, False]

Тогда

df=df[l]
3 голосов
/ 15 июня 2019

Вы можете определить свою пользовательскую функцию для поиска, если все элементы списка находятся в датафрейме B, и использовать ее с apply .

Здесь df1 - это ваш Dataframe A и df2 ваш кадр данных B:

sel = df1.apply(lambda x : all([i in df2['id'].unique() for i in x['items']]), axis=1)
finaldf = df1.loc[sel]

finaldf:

         date            items
0  2019-06-05  [121, 123, 124]
2 голосов
/ 15 июня 2019

Валентино опередил меня, поэтому идея та же:

dataframe_a[dataframe_a['items'].apply(lambda lst: all(x in dataframe_b.id.values for x in lst))]

И еще пара слов о вашем текущем подходе:

  • pd.Series.isin чекисуществует ли каждый элемент (в вашем случае каждый список) как целое в другой последовательности.Хотя ваши списки являются неупорядоченными списками, для серии кортежей порядок будет иметь значение, и проверка существования в целом - это правильное / ожидаемое поведение.
  • Другая проблема связана с вызовом isin(dataframe_b.id), который аналогичен вызовуisin(dataframe_b.id.index).Pd.Series похож на словарь, а in / содержит свойство проверяет loc / index (или ключи в терминологии словаря), а не сами значения.Если ваш loc / index содержит целые числа, которые могут совпадать с вашими идентификаторами, isin(dataframe_b.id) может неожиданно вернуть true :
In [17]: dataframe_b
Out[17]:
    id
0  121
1  122
2  123
3  124

In [18]: 121 in dataframe_b.id
Out[18]: False

In [19]: 121 in dataframe_b.id.index
Out[19]: False

In [20]: 121 in dataframe_b.id.values
Out[20]: True

In [21]: 1 in dataframe_b.id
Out[21]: True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...