Leer y escribir archivos CSV en Python con Pandas

El artículo muestra cómo leer y escribir archivos CSV utilizando la biblioteca Pandas de Python. Para leer un archivo CSV se utiliza el método `read_csv()` de la librería Pandas.

Si bien puede leer y escribir archivos CSV en Python usando la función integrada open(), o el módulo CSV dedicado, usted también puede usar pandas.

En este artículo, verás cómo usar la biblioteca de pandas de Python para leer y escribir archivos CSV.

¿Qué es un archivo CSV?

Recapitulemos rápidamente qué es un archivo CSV: nada más que un simple archivo de texto, siguiendo algunas convenciones de formato. Sin embargo, es el método más común, simple y fácil para almacenar datos tabulares. Este formato organiza las tablas siguiendo una estructura específica dividida en filas y columnas. Son estas filas y columnas las que contienen sus datos.

Una nueva línea termina cada fila para comenzar la fila siguiente. De manera similar, un delimitador, generalmente una coma, separa las columnas dentro de cada fila.

Por ejemplo, podríamos tener una tabla que se vea así:

1
2
3
4
5
6
7
| City         | State        | Capital | Population    |
| ------------ | ------------ | ------- | ------------- |
| Philadelphia | Pennsylvania | No      | 1.581 Million |
| Sacramento   | California   | Yes     | 0.5 Million   |
| New York     | New York     | No      | 8.623 Million |
| Austin       | Texas        | Yes     | 0.95 Million  |
| Miami        | Florida      | No      | 0.463 Million |

Si tuviéramos que convertirlo al formato CSV, se vería así:

1
2
3
4
5
6
City,State,Capital,Population
Philadelphia,Pennsylvania,No,1.581 Million
Sacramento,California,Yes,0.5 Million
New York,New York,No,8.623 Million
Austin,Texas,Yes,0.95 Million
Miami,Florida,No,0.463 Million

Aunque el nombre (Valores separados por comas) usa inherentemente una coma como delimitador, también puede usar otros delimitadores (separadores), como el punto y coma (;). Cada fila de la tabla es una nueva línea del archivo CSV y es una forma muy compacta y concisa de representar datos tabulares.

Ahora, echemos un vistazo a la función read_csv().

Lectura y escritura de archivos CSV con pandas {#lectura y escritura de archivos csv con pandas}

Pandas es un marco muy potente y popular para el análisis y la manipulación de datos. Una de las características más llamativas de Pandas es su capacidad para leer y escribir varios tipos de archivos, incluidos CSV y Excel. Puede manipular archivos CSV de manera fácil y efectiva en Pandas usando funciones como read_csv() y to_csv().

Instalación de pandas {#instalación de pandas}

Tenemos que instalar Pandas antes de usarlo. Usemos pip:

1
$ pip install pandas

Leer archivos CSV con read_csv()

Importemos el conjunto de datos Titanic, que se puede obtener en [GitHub] (https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv):

1
2
import pandas as pd
titanic_data = pd.read_csv('titanic.csv')

Pandas buscará este archivo en el directorio del script, naturalmente, y solo proporcionamos la ruta del archivo que nos gustaría analizar como el único argumento requerido de este método.

Echemos un vistazo al head() de este conjunto de datos para asegurarnos de que se haya importado correctamente:

1
titanic_data.head()

Esto resulta en:

1
2
3
4
5
6
   PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
1            2         1       1  ...  71.2833   C85         C
2            3         1       3  ...   7.9250   NaN         S
3            4         1       1  ...  53.1000  C123         S
4            5         0       3  ...   8.0500   NaN         S

Alternativamente, también puede leer archivos CSV de recursos en línea, como GitHub, simplemente pasando la URL del recurso a la función read_csv(). Leamos este mismo archivo CSV del repositorio de GitHub, sin descargarlo primero a nuestra máquina local:

1
2
3
4
import pandas as pd

titanic_data = pd.read_csv(r'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv')
print(titanic_data.head())

Esto también resulta en:

1
2
3
4
5
6
7
8
   PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
1            2         1       1  ...  71.2833   C85         C
2            3         1       3  ...   7.9250   NaN         S
3            4         1       1  ...  53.1000  C123         S
4            5         0       3  ...   8.0500   NaN         S

[5 rows x 12 columns]

Personalización de encabezados

De forma predeterminada, el método read_csv() utiliza la primera fila del archivo CSV como encabezado de columna. A veces, estos encabezados pueden tener nombres extraños y es posible que desee usar sus propios encabezados. Puede configurar los encabezados después de leer el archivo, simplemente asignando otra lista al campo columnas de la instancia DataFrame, o puede configurar los encabezados mientras lee el CSV en primer lugar.

Definamos una lista de nombres de columna y usemos esos nombres en lugar de los del archivo CSV:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import pandas as pd

col_names = ['Id',
             'Survived',
             'Passenger Class',
             'Full Name',
             'Gender',
             'Age',
             'SibSp',
             'Parch',
             'Ticket Number',
             'Price', 'Cabin',
             'Station']

titanic_data = pd.read_csv(r'E:\Datasets\titanic.csv', names=col_names)
print(titanic_data.head())

Vamos a ejecutar este código:

1
2
3
4
5
6
            Id  Survived Passenger Class  ...    Price  Cabin   Station
0  PassengerId  Survived          Pclass  ...     Fare  Cabin  Embarked
1            1         0               3  ...     7.25    NaN         S
2            2         1               1  ...  71.2833    C85         C
3            3         1               3  ...    7.925    NaN         S
4            4         1               1  ...     53.1   C123         S

Hmm, ahora tenemos nuestros encabezados personalizados, pero la primera fila del archivo CSV, que se usó originalmente para establecer los nombres de las columnas, también se incluye en el DataFrame. Querremos omitir esta línea, ya que ya no tiene ningún valor para nosotros.

Omitir filas al leer CSV

Abordemos este problema usando el argumento skiprows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import pandas as pd

col_names = ['Id',
             'Survived',
             'Passenger Class',
             'Full Name',
             'Gender',
             'Age',
             'SibSp',
             'Parch',
             'Ticket Number',
             'Price', 'Cabin',
             'Station']

titanic_data = pd.read_csv(r'E:\Datasets\titanic.csv', names=col_names, skiprows=[0])
print(titanic_data.head())

Ahora, ejecutemos este código:

1
2
3
4
5
6
   Id  Survived  Passenger Class  ...    Price Cabin  Station
0   1         0                3  ...   7.2500   NaN        S
1   2         1                1  ...  71.2833   C85        C
2   3         1                3  ...   7.9250   NaN        S
3   4         1                1  ...  53.1000  C123        S
4   5         0                3  ...   8.0500   NaN        S

¡Funciona de maravilla! El argumento skiprows acepta una lista de filas que le gustaría omitir. Puede omitir, por ejemplo, 0, 4, 7 si lo desea también:

1
2
titanic_data = pd.read_csv(r'E:\Datasets\titanic.csv', names=col_names, skiprows=[0, 4, 7])
print(titanic_data.head(10))

Esto daría como resultado un DataFrame que no tiene algunas de las filas que hemos visto antes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
   Id  Survived  Passenger Class  ...    Price Cabin  Station
0   1         0                3  ...   7.2500   NaN        S
1   2         1                1  ...  71.2833   C85        C
2   3         1                3  ...   7.9250   NaN        S
3   5         0                3  ...   8.0500   NaN        S
4   6         0                3  ...   8.4583   NaN        Q
5   8         0                3  ...  21.0750   NaN        S
6   9         1                3  ...  11.1333   NaN        S
7  10         1                2  ...  30.0708   NaN        C
8  11         1                3  ...  16.7000    G6        S
9  12         1                1  ...  26.5500  C103        S

Tenga en cuenta que la omisión de filas ocurre antes de que el DataFrame esté completamente formado, por lo que no perderá ningún índice del propio DataFrame, aunque, en este caso, puede ver que el campo Id (importado del archivo CSV) faltan los ID 4 y 7.

Eliminación de encabezados

También puede decidir eliminar el encabezado por completo, lo que daría como resultado un ‘DataFrame’ que simplemente tiene ‘0…n’ columnas de encabezado, configurando el argumento ’encabezado’ en ‘Ninguno’:

1
titanic_data = pd.read_csv(r'E:\Datasets\titanic.csv', header=None, skiprows=[0])

También querrá omitir la primera fila aquí, ya que si no lo hace, los valores de la primera fila se incluirán en la primera fila:

1
2
3
4
5
6
   0   1   2                                                  3       4   ...  7                 8        9 
0   1   0   3                            Braund, Mr. Owen Harris    male  ...   0         A/5 21171   7.2500
1   2   1   1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female  ...   0          PC 17599  71.2833
2   3   1   3                             Heikkinen, Miss. Laina  female  ...   0  STON/O2. 3101282   7.9250
3   4   1   1       Futrelle, Mrs. Jacques Heath (Lily May Peel)  female  ...   0            113803  53.1000
4   5   0   3                           Allen, Mr. William Henry    male  ...   0            373450   8.0500

Especificación de delimitadores

Como se indicó anteriormente, es probable que eventualmente encuentre un archivo CSV que en realidad no usa comas para separar los datos. En tales casos, puede usar el argumento sep para especificar otros delimitadores:

1
titanic_data = pd.read_csv(r'E:\Datasets\titanic.csv', sep=';')

Escribiendo archivos CSV con to_csv()

De nuevo, los DataFrames son tabulares. Convertir un DataFrame en un archivo CSV es tan simple como convertir un archivo CSV en un DataFrame: llamamos a la función write_csv() en la instancia DataFrame.

Al escribir un DataFrame en un archivo CSV, también puede cambiar los nombres de las columnas, usando el argumento columns, o especificar un delimitador a través del argumento sep. Si no especifica ninguno de estos, terminará con un archivo estándar de valores separados por comas.

Juguemos con esto:

1
2
3
import pandas as pd
cities = pd.DataFrame([['Sacramento', 'California'], ['Miami', 'Florida']], columns=['City', 'State'])
cities.to_csv('cities.csv')

Aquí, hemos creado un DataFrame simple con dos ciudades y sus respectivos estados. Luego, seguimos adelante y guardamos esos datos en un archivo CSV usando to_csv() y proporcionando el nombre del archivo.

Esto da como resultado un nuevo archivo en el directorio de trabajo del script que está ejecutando, que contiene:

1
2
3
,City,State
0,Sacramento,California
1,Miami,Florida

Sin embargo, esto no está realmente bien formateado. Todavía tenemos los índices del DataFrame, que también pone un extraño punto perdido antes de los nombres de las columnas. Si volviéramos a importar este CSV a un DataFrame, sería un desastre:

1
2
df = pd.read_csv('cities.csv')
print(df)

Esto resulta en:

1
2
3
   Unnamed: 0        City       State
0           0  Sacramento  California
1           1       Miami     Florida

Los índices del DataFrame terminaron convirtiéndose en una nueva columna, que ahora es Sin nombre.

Al guardar el archivo, asegurémonos de soltar el índice de DataFrame:

1
2
3
import pandas as pd
cities = pd.DataFrame([['Sacramento', 'California'], ['Miami', 'Florida']], columns=['City', 'State'])
cities.to_csv('cities.csv', index=False)

Ahora, esto da como resultado un archivo que contiene:

1
2
3
City,State
Sacramento,California
Miami,Florida

¡Funciona de maravilla! Si lo volvemos a importar e imprimimos el contenido, el DataFrame está bien construido:

1
2
df = pd.read_csv('cities.csv')
print(df)

Esto resulta en:

1
2
3
         City       State
0  Sacramento  California
1       Miami     Florida

Personalización de encabezados

Cambiemos los encabezados de columna de los predeterminados:

1
2
3
4
import pandas as pd
cities = pd.DataFrame([['Sacramento', 'California'], ['Miami', 'Florida']], columns=['City', 'State'])
new_column_names = ['City_Name', 'State_Name']
cities.to_csv('cities.csv', index=False, header=new_column_names)

Hemos creado una lista new_header, que contiene diferentes valores para nuestras columnas. Luego, usando el argumento header, hemos configurado estos en lugar de los nombres de columna originales. Esto genera un cities.csv con estos contenidos:

1
2
3
4
City_Name,State_Name
Sacramento,California
Miami,Florida
Washington DC,Unknown

Personalización del delimitador

Cambiemos el delimitador del valor predeterminado (,) a uno nuevo:

1
2
3
import pandas as pd
cities = pd.DataFrame([['Sacramento', 'California'], ['Miami', 'Florida']], columns=['City', 'State'])
cities.to_csv('cities.csv', index=False, sep=';')

Esto da como resultado un archivo cities.csv que contiene:

1
2
3
City;State
Sacramento;California
Miami;Florida

Manejo de valores faltantes

A veces, DataFrame tiene valores faltantes que hemos dejado como NaN o NA. En tales casos, es posible que desee formatearlos cuando los escriba en un archivo CSV. Puede usar el argumento na_rep y establecer el valor que se va a poner en lugar de un valor faltante:

1
2
3
import pandas as pd
cities = pd.DataFrame([['Sacramento', 'California'], ['Miami', 'Florida'], ['Washington DC', pd.NA]], columns=['City', 'State'])
cities.to_csv('cities.csv', index=False, na_rep='Unknown')

Aquí, tenemos dos pares de ciudad-estado válidos, pero a ‘Washington DC’ le falta su estado. Si ejecutamos este código, dará como resultado un cities.csv con los siguientes contenidos:

1
2
3
4
City,State
Sacramento,California
Miami,Florida
Washington DC,Unknown

Conclusión

El artículo muestra cómo leer y escribir archivos CSV utilizando la biblioteca Pandas de Python. Para leer un archivo CSV se utiliza el método read_csv() de la librería Pandas. También puede pasar nombres de encabezado personalizados mientras lee archivos CSV a través del atributo names del método read_csv(). Finalmente, para escribir un archivo CSV usando Pandas, primero debe crear un objeto Pandas DataFrame y luego llamar al método to_csv en el DataFrame.