Выберите строки в кадре данных панд, если все столбцы содержат определенный шаблон - PullRequest
0 голосов
/ 16 января 2019

У меня следующий фрейм данных

id  pattern1    pattern2    pattern3
 1  a-b-c       a-b--       a-b-c
 2  a-a--       a-b--       a-c--
 3  a-v--       a-m--       a-k--
 4  a-b--       a-n--       a-n-c

Я хочу отфильтровать строки, содержащие шаблон - в конце во всех столбцах. В этом случае вывод будет

 2  a-a--       a-b--       a-c--
 3  a-v--       a-m--       a-k--

Пока я могу думать только о том, чтобы сделать что-то вроде следующего

df[(len(df['pattern1'].str.split('--')[1])==0) & \
   (len(df['pattern2'].str.split('--')[1])==0) & \
   (len(df['pattern3'].str.split('--')[1])==0)]

Это не работает. Кроме того, я не могу написать имена всех столбцов, так как 20 столбцов. Как я могу отфильтровать строки, где все столбцы в этой строке соответствуют определенному шаблону / условию?

1 Ответ

0 голосов
/ 16 января 2019

Начните с установки «id» в качестве индекса, если это еще не сделано.

df = df.set_index('id')

Одна опция для проверки каждой строки использует applymap, вызывая str.endswith:

df[df.applymap(lambda x: x.endswith('--')).all(1)]

   pattern1 pattern2 pattern3
id                           
2     a-a--    a-b--    a-c--
3     a-v--    a-m--    a-k--

Другим вариантом является apply вызов pd.Series.str.endswith для каждого столбца:

df[df.apply(lambda x: x.str.endswith('--')).all(1)]

   pattern1 pattern2 pattern3
id                           
2     a-a--    a-b--    a-c--
3     a-v--    a-m--    a-k--

Наконец, для повышения производительности вы можете И маскировать внутри понимания списка, используя logical_and.reduce:

# m = np.logical_and.reduce([df[c].str.endswith('--') for c in df.columns])
m = np.logical_and.reduce([
    [x.endswith('--') for x in df[c]] for c in df.columns])
m
# array([False,  True,  True, False])

df[m]
   pattern1 pattern2 pattern3
id                           
2     a-a--    a-b--    a-c--
3     a-v--    a-m--    a-k--

Если есть другие столбцы, но вы хотите учитывать только те, которые называются «pattern *», вы можете использовать filter в DataFrame:

u = df.filter(like='pattern')

Теперь повторите описанные выше параметры, используя u, например, первый вариант будет

df[u.applymap(lambda x: x.endswith('--')).all(1)]

... и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...