Pandas isin с несколькими столбцами

Я хочу выбрать все строки в фрейме данных, которые содержат значения, определенные в списке. У меня есть два подхода, которые не работают так, как ожидалось / хотелось.

Мой фрейм данных выглядит примерно так:

Timestamp DEVICE READING VALUE
1 | DEV1 | READ1 | randomvalue
2 | DEV1 | READ2 | randomvalue
3 | DEV2 | READ1 | randomvalue
4 | DEV2 | READ2 | randomvalue
5 | DEV3 | READ1 | randomvalue

и у меня есть список (ls), как показано ниже:

[[DEV1, READ1], [DEV1, READ2], [DEV2,READ1]]

В этом сценарии я хочу удалить строки 4 и 5:

Мой первый подход был:

df = df[(df['DEVICE']. isin([ls[i][0] for i in range(len(ls))])) &
        (df['READING'].isin([ls[k][1] for k in range(len(ls))]))]

Проблема с этим, очевидно, заключается в том, что он не удаляет строку 4, потому что DEV2 имеет READING READ2, но он должен удалить его.

Мой второй подход был:

df = df[(df[['DEVICE','READING']].isin({'DEVICE':  [ls[i][0] for i in range(len(ls))],
                                        'READING': [ls[i][1] for i in range(len(ls))] }))]

Он выбирает правильные строки, но не удаляет другие строки. Вместо этого он устанавливает для всех остальных ячеек значение NaN, включая СТРОКУ ЗНАЧЕНИЙ, которую я хочу сохранить. И он не накапливает оба, поэтому строка 4 выглядит как 4 |DEV2|NaN|NaN

Что было бы самым простым или лучшим способом решить эту проблему? Вы можете мне помочь?

~ Фабиан

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
7
0
8 004
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

По какой причине вы этого не делаете?

df.drop([4,5],axis=0,inplace=True)

Это всего лишь пример. Df, с которым я работаю, содержит> 5000 значений, а список, который я использую, также немного длиннее> 15. И он динамический, основанный на реальных событиях.

PythonF 09.11.2018 01:14
Ответ принят как подходящий

Вы можете преобразовать список в список кортежей. Преобразуйте необходимые столбцы в фрейме данных в кортежи и используйте isin

l = [['DEV1', 'READ1'], ['DEV1', 'READ2'], ['DEV2','READ1']]
l = [tuple(i) for i in l]
df[df[['DEVICE', 'READING']].apply(tuple, axis = 1).isin(l)]

Ты получаешь

    Timestamp   DEVICE  READING VALUE
0   1   DEV1    READ1   randomvalue
1   2   DEV1    READ2   randomvalue
2   3   DEV2    READ1   randomvalue

Это должно делать то, что вы хотите

import pandas as pd

df = pd.DataFrame({'a':[1,1,0,0,1], 'b':[0,0,1,0,1]})

keepers = [[0,0],[1,1]]

df = df[df.apply(lambda row: [row['a'], row['b']] in keepers, axis=1)]

здесь моя переменная keepers будет вашим списком [[DEV1, READ1], [DEV1, READ2], [DEV2, READ1]]

James Fulton 09.11.2018 01:30

Вы можете использовать мультииндекс для решения этой проблемы.

values = [['DEV1', 'READ1'], ['DEV1', 'READ2'], ['DEV2', 'READ1']]
# DataFrame.loc requires tuples for multi-index lookups
index_values = [tuple(v) for v in values]

filtered = df.set_index(['DEVICE', 'READING']).loc[index_values].reset_index()
print(filtered)

  DEVICE READING  Timestamp        VALUE
0   DEV1   READ1          1  randomvalue
1   DEV1   READ2          2  randomvalue
2   DEV2   READ1          3  randomvalue  

У вас также могут быть значения (в первой строке) из другого фрейма данных, например. values ​​= df1 [['DEV1],' READ1 ']]. values

Yasmin 22.01.2019 19:03

Другие вопросы по теме