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

Например

    code tag number floor  note
1   1111  *   **     34     no 
2   2323  7   899     7     no
3   3677  #   900    11     no
4   9897  10  134    *      no
5    #    #   566    11     no
6   3677  55  908    11     no

Я хочу отфильтровать все строки, содержащие #, *, ** в столбцах код, тег, номер, этаж.

Что я хочу получить это

    code tag number floor  note
1   1111  *   **     34     no 
3   3677  #   900    11     no
4   9897  10  134    *      no
5    #    #   566    11     no

Я пытался использовать метод isin во фрейме данных, но он работает с одним столбцом, но не работает с несколькими столбцами. Благодарность!

2
MMM 29 Авг 2017 в 22:51

3 ответа

Лучший ответ

Вариант 1
Предполагая, что нет других ранее существовавших pir

df[df.replace(['#', '*', '**'], 'pir').eq('pir').any(1)]

   code tag number floor note
1  1111   *     **    34   no
3  3677   #    900    11   no
4  9897  10    134     *   no
5     #   #    566    11   no

Вариант 2
Вредное numpy вещание. Сначала быстрый, но масштабируется квадратично

df[(df.values[None, :] == np.array(['*', '**', '#'])[:, None, None]).any(0).any(1)]

   code tag number floor note
1  1111   *     **    34   no
3  3677   #    900    11   no
4  9897  10    134     *   no
5     #   #    566    11   no

Вариант 3
Менее неприятный np.in1d

df[np.in1d(df.values, ['*', '**', '#']).reshape(df.shape).any(1)]

   code tag number floor note
1  1111   *     **    34   no
3  3677   #    900    11   no
4  9897  10    134     *   no
5     #   #    566    11   no

Вариант 4
Сверху map

df[list(
    map(bool,
        map({'*', '**', '#'}.intersection,
            map(set,
                zip(*(df[c].values.tolist() for c in df)))))
)]

   code tag number floor note
1  1111   *     **    34   no
3  3677   #    900    11   no
4  9897  10    134     *   no
5     #   #    566    11   no
1
piRSquared 29 Авг 2017 в 20:30

Вы также можете использовать df.applymap:

s = {'*', '**', '#'}
df[df.applymap(lambda x: x in s).max(1)]

   code tag number floor note
1  1111   *     **    34   no
3  3677   #    900    11   no
4  9897  10    134     *   no
5     #   #    566    11   no

PiR предлагается сумасшедшая (но это работает!) альтернатива:

df[df.apply(set, 1) & {'*', '**', '#'}]

   code tag number floor note
1  1111   *     **    34   no
3  3677   #    900    11   no
4  9897  10    134     *   no
5     #   #    566    11   no
1
cs95 29 Авг 2017 в 20:12

Я думаю, вам нужны apply, isin и any с логическим индексированием:

list = ['#','*','**']
cols = ['code','tag','number','floor']
df[df[cols].apply(lambda x: x.isin(list).any(), axis=1)]

Выход:

   code tag number floor note
1  1111   *     **    34   no
3  3677   #    900    11   no
4  9897  10    134     *   no
5     #   #    566    11   no
1
Scott Boston 29 Авг 2017 в 19:58