Панды Исин с несколькими столбцами - PullRequest
0 голосов
/ 09 ноября 2018

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

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

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, включая VALUE ROW, которую я хочу сохранить. И он не накапливает оба, поэтому строка 4 выглядит как 4 |DEV2|NaN|NaN

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

~ Fabian

Ответы [ 4 ]

0 голосов
/ 09 ноября 2018

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

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  
0 голосов
/ 09 ноября 2018

Вы можете преобразовать список в список кортежей. Преобразуйте необходимые столбцы в кадре данных в кортежи и используйте 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
0 голосов
/ 09 ноября 2018

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

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)]
0 голосов
/ 09 ноября 2018

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

df.drop([4,5],axis=0,inplace=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...