¿Cómo puedo eliminar los espacios en blanco adicionales de las cadenas al analizar un archivo csv en Pandas?

5 minutos de lectura

avatar de usuario de mpjan
mpjan

Tengo el siguiente archivo llamado ‘data.csv’:

    1997,Ford,E350
    1997, Ford , E350
    1997,Ford,E350,"Super, luxurious truck"
    1997,Ford,E350,"Super ""luxurious"" truck"
    1997,Ford,E350," Super luxurious truck "
    "1997",Ford,E350
    1997,Ford,E350
    2000,Mercury,Cougar

Y me gustaría analizarlo en un DataFrame de pandas para que el DataFrame se vea de la siguiente manera:

       Year     Make   Model              Description
    0  1997     Ford    E350                     None
    1  1997     Ford    E350                     None
    2  1997     Ford    E350   Super, luxurious truck
    3  1997     Ford    E350  Super "luxurious" truck
    4  1997     Ford    E350    Super luxurious truck
    5  1997     Ford    E350                     None
    6  1997     Ford    E350                     None
    7  2000  Mercury  Cougar                     None

Lo mejor que pude hacer fue:

    pd.read_table("data.csv", sep=r',', names=["Year", "Make", "Model", "Description"])

Lo que me pone:

    Year     Make   Model              Description
 0  1997     Ford    E350                     None
 1  1997    Ford     E350                     None
 2  1997     Ford    E350   Super, luxurious truck
 3  1997     Ford    E350  Super "luxurious" truck
 4  1997     Ford    E350   Super luxurious truck 
 5  1997     Ford    E350                     None
 6  1997     Ford    E350                     None
 7  2000  Mercury  Cougar                     None

¿Cómo puedo obtener el DataFrame sin esos espacios en blanco?

Podrías usar convertidores:

import pandas as pd

def strip(text):
    try:
        return text.strip()
    except AttributeError:
        return text

def make_int(text):
    return int(text.strip('" '))

table = pd.read_table("data.csv", sep=r',',
                      names=["Year", "Make", "Model", "Description"],
                      converters = {'Description' : strip,
                                    'Model' : strip,
                                    'Make' : strip,
                                    'Year' : make_int})
print(table)

rendimientos

   Year     Make   Model              Description
0  1997     Ford    E350                     None
1  1997     Ford    E350                     None
2  1997     Ford    E350   Super, luxurious truck
3  1997     Ford    E350  Super "luxurious" truck
4  1997     Ford    E350    Super luxurious truck
5  1997     Ford    E350                     None
6  1997     Ford    E350                     None
7  2000  Mercury  Cougar                     None

Agregar parámetro skipinitialspace=True a read_table trabajó para mi.

Así que prueba:

pd.read_table("data.csv", 
              sep=r',', 
              names=["Year", "Make", "Model", "Description"], 
              skipinitialspace=True)

Lo mismo funciona en pd.read_csv().

  • Esto me ayudó. Tengo valores como “NaN” en los datos y esto hace que detecte los NaN sin importar cuántos espacios en blanco haya delante de “NaN” y sin configurar manualmente el parámetro “na_values”.

    – Dremet

    21 de febrero de 2017 a las 9:56

  • Si bien los convertidores pueden hacerlo y mucho más, para la mayoría de los casos de uso, skipinitialspace=True es lo que la gente quiere. ¡Probablemente debería ser la mejor respuesta!

    – travc

    6 de abril de 2018 a las 0:15

Bueno, el espacio en blanco está en sus datos, por lo que no puede leer los datos sin leer en el espacio en blanco. Sin embargo, después de leerlo, puede quitar el espacio en blanco haciendo, por ejemplo, df["Make"] = df["Make"].map(str.strip) (dónde df es su marco de datos).

  • Súper útil, especialmente cuando se envía a un archivo txt donde no necesitaba un encabezado o índice. Esta es la única solución que funcionó. df["Make"] = df["Make"].map(str.strip) luego apliqué df.to_csv('no_head.txt',header=None,index=False) y esto eliminó los espacios en blanco. gracias de nuevo

    – Ted Taylor de la vida

    26 de febrero de 2018 a las 16:20


No creo que Pandas admitiera esto en el momento en que se publicó esta pregunta, pero la forma más sencilla de hacerlo es mediante el uso de expresiones regulares en el sep parámetro de read_csv. Así que algo como lo siguiente debería funcionar para este problema.

table = pd.read_table("data.csv", sep=' *, *')

Avatar de usuario de RKD314
RKD314

No tengo suficiente reputación para dejar un comentario, pero la respuesta anterior sugiere usar el map funcionar junto con strip no funcionará si tiene valores de NaN, ya que strip solo funciona en caracteres y NaN son flotantes.

Hay una función de pandas incorporada para hacer esto, que usé:
pd.core.strings.str_strip(df['Description'])

dónde df es su marco de datos. En mi caso, lo usé en un marco de datos con ~1,2 millones de filas y fue muy rápido.

  • Esta respuesta envejeció bien. “No tiene suficiente reputación”. Tiene 595 en este momento y una insignia de oro.

    – Viragos

    27 sep 2019 a las 15:53

Avatar de usuario de la comunidad
Comunidad

leer_tabla es ObsoletoAquí está el mensaje tal como aparece en la documentación.

En desuso desde la versión 0.24.0.

Usar pandas.read_csv() en su lugar, pasando sep=’\t’ si es necesario.

entonces usando leer_csv puede pasar una expresión regular para el sep argumento, donde puede especificar el separador como

sep="\s*,\s*"

cualquier número de espacios, seguido de un separador, seguido de cualquier número de espacios nuevamenteesto asegurará que todos los espacios iniciales y finales también se elijan como un fragmento delimitador que, a su vez, elimina los espacios en blanco a ambos lados de sus datos.

detalles de expresiones regulares de la siguiente manera:

\s -> white-space
* -> any number (zero or many)
, -> no meaning, direct character match

Entonces, la expresión regular \s*,\s* representa white-space[any number] match a comma and white-space[any number].

si su delimitador es algo más que una coma, reemplace el , en la expresión anterior con su delimitador. P.ej: \s*;\s* si ; es su delimitador.

  • Esta respuesta envejeció bien. “No tiene suficiente reputación”. Tiene 595 en este momento y una insignia de oro.

    – Viragos

    27 sep 2019 a las 15:53

Avatar de usuario de J Wang
J wang

Aquí hay una función para recorrer cada columna y aplicar pd.core.strings.str_strip:

def df_strip(df):
  df = df.copy()
  for c in df.columns:
    if df[c].dtype == np.object:
      df[c] = pd.core.strings.str_strip(df[c])
    df = df.rename(columns={c:c.strip()})
  return df

  • Función realmente útil para tratar un marco de datos. Recuerda devolver el objeto, df = df_strip(df)

    – Che Testa

    9 de marzo de 2020 a las 15:42


¿Ha sido útil esta solución?