Estoy buscando una manera eficiente de eliminar partes no deseadas de las cadenas en una columna DataFrame.
Los datos se ven así:
time result
1 09:00 +52A
2 10:00 +62B
3 11:00 +44a
4 12:00 +30b
5 13:00 -110a
Necesito recortar estos datos para:
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
Lo intenté .str.lstrip('+-')
y. str.rstrip('aAbBcC')
, pero recibí un error:
TypeError: wrapper() takes exactly 1 argument (2 given)
Cualquier sugerencia sería muy apreciada!
6 años después de que se publicó la pregunta original, los pandas ahora tienen un buen número de funciones de cadena "vectorizadas" que pueden realizar de manera sucinta estas operaciones de manipulación de cadenas.
Esta respuesta explorará algunas de estas funciones de cadena, sugerirá alternativas más rápidas y realizará una comparación de tiempos al final.
.str.replace
Especifique la subcadena / patrón para que coincida y la subcadena para reemplazarlo.
Si necesita convertir el resultado en un entero, puede usar
Series.astype
,Si no desea modificar
df
en el lugar, useDataFrame.assign
:.str.extract
Útil para extraer la (s) subcadena (s) que desea conservar.
Con
extract
, es necesario especificar al menos un grupo de captura.expand=False
devolverá una serie con los elementos capturados del primer grupo de captura..str.split
y.str.get
La división funciona suponiendo que todas sus cadenas sigan esta estructura consistente.
No lo recomiende si está buscando una solución general.
Optimización: Lista de comprensiones
En algunas circunstancias, las comprensiones de listas deben ser favorecidas sobre las funciones de cadena de pandas. La razón es que las funciones de cadena son inherentemente difíciles de vectorizar (en el verdadero sentido de la palabra), por lo que la mayoría de las funciones de cadena y expresión regular son solo envoltorios alrededor de bucles con más sobrecarga.
Mi artículo, ¿son realmente malos los bucles for pandas? ¿Cuándo debería importarme?, entra en mayor detalle.
La
str.replace
opción puede reescribirse usandore.sub
El
str.extract
ejemplo puede reescribirse usando una lista de comprensión conre.search
,Si NaNs o no coincide son una posibilidad, deberá volver a escribir lo anterior para incluir alguna comprobación de errores. Hago esto usando una función.
También podemos reescribir las respuestas de @eumiro y @MonkeyButter usando listas de comprensión:
Y,
Se aplican las mismas reglas para manejar NaN, etc.
Comparación de rendimiento
Gráficos generados usando perfplot . Listado completo de códigos, para su referencia. Las funciones relevantes se enumeran a continuación.
Algunas de estas comparaciones son injustas porque aprovechan la estructura de los datos de OP, pero toman de ella lo que quieran. Una cosa a tener en cuenta es que cada función de comprensión de la lista es más rápida o comparable que su variante de pandas equivalente.
Las funciones
fuente
Try using .loc[row_indexer,col_indexer] = value instead
Usaría la función de reemplazo de pandas, muy simple y potente, ya que puede usar regex. A continuación, estoy usando la expresión regular \ D para eliminar cualquier carácter que no sea un dígito, pero obviamente podrías ser bastante creativo con la expresión regular.
fuente
df.loc[:, 'column_a'].replace(regex=True, to_replace="my_prefix", value="new_prefix")
. Serie:. Esto convertirá una cadena como "my_prefixaaa" a "new_prefixaaa".En el caso particular en el que conoce el número de posiciones que desea eliminar de la columna del marco de datos, puede usar la indexación de cadenas dentro de una función lambda para deshacerse de esas partes:
Último personaje:
Primeros dos personajes:
fuente
Hay un error aquí: actualmente no puede pasar argumentos a
str.lstrip
ystr.rstrip
:http://github.com/pydata/pandas/issues/2411
EDITAR: 2012-12-07 esto funciona ahora en la rama de desarrollo:
fuente
Un método muy simple sería usar el
extract
método para seleccionar todos los dígitos. Simplemente proporcione la expresión regular'\d+'
que extrae cualquier número de dígitos.fuente
A menudo uso listas de comprensión para este tipo de tareas porque a menudo son más rápidas.
Puede haber grandes diferencias en el rendimiento entre los diversos métodos para hacer cosas como esta (es decir, modificar cada elemento de una serie dentro de un Marco de datos). A menudo, la comprensión de la lista puede ser más rápida: consulte la carrera de código a continuación para esta tarea:
fuente
Suponga que su DF también tiene esos caracteres adicionales entre números. La última entrada.
Puede intentar str.replace para eliminar caracteres no solo desde el principio y el final, sino también desde el medio.
Salida:
fuente
Intenta esto usando una expresión regular:
fuente