более простой Python-эквивалент grep в R-стиле, включая несколько вещей для сопоставления - PullRequest
0 голосов
/ 15 февраля 2019

Этот вопрос является почти дубликатом этого , с некоторыми изменениями.

Возьмите следующий фрейм данных и найдите позиции столбцов, которые имеют "sch" или "оа "в них.Достаточно просто в R:

df <- data.frame(cheese = rnorm(10),
                 goats = rnorm(10), 
                 boats = rnorm(10), 
                 schmoats = rnorm(10), 
                 schlomo = rnorm(10),
                 cows = rnorm(10))

grep("oa|sch", colnames(df))

[1] 2 3 4 5

write.csv(df, file = "df.csv")

Теперь, в Python, я мог бы использовать некоторое подробное понимание списка:

import pandas as pd
df = pd.read_csv("df.csv", index_col = 0)
matches = [i for i in range(len(df.columns)) if "oa" in df.columns[i] or "sch" in df.columns[i]]

matches
Out[10]: [1, 2, 3, 4]

Я хотел бы знать, если есть лучшеспособ сделать это в Python, чем приведенный выше пример понимания списка .В частности, что, если у меня есть десятки строк, чтобы соответствовать.В R я мог бы сделать что-то вроде

regex <- paste(vector_of_strings, sep = "|")
grep(regex, colnames(df))

Но не очевидно, как это сделать, используя списочное понимание в python .Может быть, я мог бы использовать манипуляции со строками, чтобы программно создать строку, которая будет выполняться внутри списка, чтобы справиться со всеми повторяющимися операторами or?

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Используйте pandas ' DataFrame.filter для запуска того же регулярного выражения:

df.filter(regex = "oa|sch").columns
# Index(['goats', 'boats', 'schmoats', 'schlomo'], dtype='object')

df.filter(regex = "oa|sch").columns.values
# ['goats' 'boats' 'schmoats' 'schlomo']

Данные

import numpy as np
import pandas as pd

np.random.seed(21419)

df = pd.DataFrame({'cheese': np.random.randn(10),
                   'goats': np.random.randn(10), 
                   'boats': np.random.randn(10), 
                   'schmoats': np.random.randn(10), 
                   'schlomo': np.random.randn(10),
                   'cows': np.random.randn(10)})

И для поиска нескольких строк:

rgx = "|".join(list_of_strings)

df.filter(regex = rgx)

Чтобы вернуть индексы, рассмотрим это векторизованное решение с numy из @ Divakar .Обратите внимание, в отличие от R, Python индексируется нулями.

def column_index(df, query_cols):
    cols = df.columns.values
    sidx = np.argsort(cols)
    return sidx[np.searchsorted(cols,query_cols,sorter=sidx)]

column_index(df, df.filter(regex="oa|sch").columns)
# [1 2 3 4] 
0 голосов
/ 15 февраля 2019

Возможно, вы ищете модуль re?

import re
pattern = re.compile("oa|sch")
[i for i in range(len(df.columns)) if pattern.search(df.columns[i])]
# [1, 2, 3, 4]

Может быть, не самый хороший по сравнению с векторизацией R, но понимание списка должно быть в порядке.

И если выхотел объединить строки вместе, вы могли бы сделать что-то вроде

"|".join(("oa", "sch"))
# 'oa|sch'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...