Como extrair maiúsculas e também algumas substring do dataframe do pandas usando extract?
Esta questão é a questão de acompanhamento da questão anterior. Como extrair apenas substring em maiúsculas da série de pandas? .
Em vez de mudar a velha pergunta, decidi fazer a nova.
Meu objetivo é extrair o método de agregação agge o nome featdo recurso de uma coluna chamada item.
Aqui está a questão:
import numpy as np
import pandas as pd
df = pd.DataFrame({'item': ['num','bool', 'cat', 'cat.COUNT(example)','cat.N_MOST_COMMON(example.ord)[2]','cat.FIRST(example.ord)','cat.FIRST(example.num)']})
regexp = (r'(?P<agg>) ' # agg is the word in uppercase (all other substring is lowercased)
r'(?P<feat>), ' # 1. if there is no uppercase, whole string is feat
# 2. if there is uppercase the substring after example. is feat
# e.g. cat ==> cat
# cat.N_MOST_COMMON(example.ord)[2] ==> ord
)
df[['agg','feat']] = df.col.str.extract(regexp,expand=True)
# I am not sure how to build up regexp here.
print(df)
"""
Required output
item agg feat
0 num num
1 bool bool
2 cat cat
3 cat.COUNT(example) COUNT # note: here feat is empty
4 cat.N_MOST_COMMON(example.ord)[2] N_MOST_COMMON ord
5 cat.FIRST(example.ord) FIRST ord
6 cat.FIRST(example.num) FIRST num
""";
Respostas
Pois feat, uma vez que você já obteve a resposta aggem sua outra pergunta sobre StackOverflow, acho que você pode usar o seguinte para extrair duas séries diferentes baseadas em dois padrões diferentes que são separados com |e, em seguida, fillna()uma série com outra.
^([^A-Z]*$)só deve retornar a string completa se a string completa estiver em minúsculas[^a-z].*example\.([a-z]+)\).*$só deve retornar strings depoisexample.e antes de)apenas se houver letras maiúsculas na string antes deexample.
df = pd.DataFrame({'item': ['num','bool', 'cat', 'cat.COUNT(example)','cat.N_MOST_COMMON(example.ord)[2]','cat.FIRST(example.ord)','cat.FIRST(example.num)']})
s = df['item'].str.extract('^([^A-Z]*$)|[^a-z].*example\.([a-z]+)\).*$', expand=True)
df['feat'] = s[0].fillna(s[1]).fillna('')
df
Out[1]:
item feat
0 num num
1 bool bool
2 cat cat
3 cat.COUNT(example)
4 cat.N_MOST_COMMON(example.ord)[2] ord
5 cat.FIRST(example.ord) ord
6 cat.FIRST(example.num) num
O item acima fornece a saída que você está procurando para seus dados de amostra e mantém suas condições. Contudo:
- E se houver MAIÚSCULAS depois
example.? A saída atual retornaria''
veja o exemplo # 2 abaixo com alguns dos dados alterados de acordo com o ponto acima:
df = pd.DataFrame({'item': ['num','cat.count(example.AAA)', 'cat.count(example.aaa)', 'cat.count(example)','cat.N_MOST_COMMON(example.ord)[2]','cat.FIRST(example.ord)','cat.FIRST(example.num)']})
s = df['item'].str.extract('^([^A-Z]*$)|[^a-z].*example\.([a-z]+)\).*$', expand=True)
df['feat'] = s[0].fillna(s[1]).fillna('')
df
Out[2]:
item feat
0 num num
1 cat.count(example.AAA)
2 cat.count(example.aaa) cat.count(example.aaa)
3 cat.count(example) cat.count(example)
4 cat.N_MOST_COMMON(example.ord)[2] ord
5 cat.FIRST(example.ord) ord
6 cat.FIRST(example.num) num