Estou procurando uma maneira eficiente de remover partes indesejadas de seqüências de caracteres em uma coluna DataFrame.
Os dados se parecem com:
time result
1 09:00 +52A
2 10:00 +62B
3 11:00 +44a
4 12:00 +30b
5 13:00 -110a
Preciso aparar esses dados para:
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
Eu tentei .str.lstrip('+-')
e. str.rstrip('aAbBcC')
, mas ocorreu um erro:
TypeError: wrapper() takes exactly 1 argument (2 given)
Qualquer ponteiro seria muito apreciado!
Seis anos após a publicação da pergunta original, o pandas agora possui um bom número de funções de string "vetorizadas" que podem executar sucintamente essas operações de manipulação de strings.
Esta resposta irá explorar algumas dessas funções de string, sugerir alternativas mais rápidas e entrar em uma comparação de tempos no final.
.str.replace
Especifique a substring / padrão para corresponder e a substring para substituí-lo.
Se você precisar converter o resultado em um número inteiro, poderá usar
Series.astype
,Se você não deseja modificar
df
no local, useDataFrame.assign
:.str.extract
Útil para extrair a substring (s) que você deseja manter.
Com
extract
, é necessário especificar pelo menos um grupo de captura.expand=False
retornará uma série com os itens capturados do primeiro grupo de capturas..str.split
e.str.get
A divisão funciona assumindo que todas as suas strings seguem essa estrutura consistente.
Não recomende se você estiver procurando uma solução geral.
Otimizando: compreensões da lista
Em algumas circunstâncias, a compreensão da lista deve ser preferida às funções de string dos pandas. O motivo é que as funções de string são inerentemente difíceis de vetorizar (no verdadeiro sentido da palavra), portanto, a maioria das funções de string e regex são apenas wrappers em torno de loops com mais sobrecarga.
Meu artigo: Os loops de pandas são realmente ruins? Quando devo me importar? , entra em maiores detalhes.
A
str.replace
opção pode ser reescrita usandore.sub
O
str.extract
exemplo pode ser reescrito usando uma compreensão de lista comre.search
,Se NaNs ou não correspondências forem possíveis, você precisará reescrever o item acima para incluir alguma verificação de erro. Eu faço isso usando uma função.
Também podemos reescrever as respostas de @ eumiro e @ MonkeyButter usando a compreensão de lista:
E,
Aplicam-se as mesmas regras para o tratamento de NaNs, etc.
Comparação de desempenho
Gráficos gerados usando perfplot . Listagem de código completo, para sua referência. As funções relevantes estão listadas abaixo.
Algumas dessas comparações são injustas porque tiram vantagem da estrutura dos dados do OP, mas tiram dela o que você deseja. Uma coisa a notar é que toda função de compreensão de lista é mais rápida ou comparável do que sua variante equivalente de pandas.
Funções
fonte
Try using .loc[row_indexer,col_indexer] = value instead
eu usaria a função de substituição de pandas, muito simples e poderosa, como você pode usar regex. Abaixo, estou usando o regex \ D para remover caracteres que não sejam dígitos, mas obviamente você pode ser bastante criativo com o regex.
fonte
df.loc[:, 'column_a'].replace(regex=True, to_replace="my_prefix", value="new_prefix")
. Isso converterá uma string como "my_prefixaaa" em "new_prefixaaa".No caso específico em que você sabe o número de posições que deseja remover da coluna do quadro de dados, pode usar a indexação de cadeias dentro de uma função lambda para se livrar dessas partes:
Último caractere:
Primeiros dois caracteres:
fonte
Há um erro aqui: atualmente não é possível transmitir argumentos para
str.lstrip
estr.rstrip
:http://github.com/pydata/pandas/issues/2411
EDIT: 2012-12-07 isso funciona agora no ramo dev:
fonte
Um método muito simples seria usar o
extract
método para selecionar todos os dígitos. Basta fornecer a expressão regular'\d+'
que extrai qualquer número de dígitos.fonte
Costumo usar a compreensão da lista para esses tipos de tarefas, porque geralmente são mais rápidas.
Pode haver grandes diferenças no desempenho entre os vários métodos para fazer coisas como esta (isto é, modificar todos os elementos de uma série dentro de um DataFrame). Geralmente, a compreensão da lista pode ser mais rápida - veja a corrida de código abaixo para esta tarefa:
fonte
Suponha que seu DF também tenha esses caracteres extras entre os números. A última entrada.
Você pode tentar str.replace para remover caracteres não apenas do início e do fim, mas também do meio.
Resultado:
fonte
Tente isso usando expressão regular:
fonte