Я хочу выбрать все строки в фрейме данных, которые содержат значения, определенные в списке. У меня есть два подхода, которые не работают так, как ожидалось / хотелось.
Мой фрейм данных выглядит примерно так:
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
Что было бы самым простым или лучшим способом решить эту проблему? Вы можете мне помочь?
~ Фабиан






По какой причине вы этого не делаете?
df.drop([4,5],axis=0,inplace=True)
Вы можете преобразовать список в список кортежей. Преобразуйте необходимые столбцы в фрейме данных в кортежи и используйте 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]]
Вы можете использовать мультииндекс для решения этой проблемы.
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
Это всего лишь пример. Df, с которым я работаю, содержит> 5000 значений, а список, который я использую, также немного длиннее> 15. И он динамический, основанный на реальных событиях.