¿Cómo leo y escribo archivos CSV?

Resuelto Martin Thoma asked hace 7 años • 7 respuestas

¿Cómo leo el siguiente archivo CSV?

1,"A towel,",1.0
42," it says, ",2.0
1337,is about the most ,-1
0,massively useful thing ,123
-2,an interstellar hitchhiker can have.,3

¿ Cómo escribo lo siguiente dataen un archivo CSV?

data = [
    (1, "A towel,", 1.0),
    (42, " it says, ", 2.0),
    (1337, "is about the most ", -1),
    (0, "massively useful thing ", 123),
    (-2, "an interstellar hitchhiker can have.", 3),
]
Martin Thoma avatar Jan 11 '17 14:01 Martin Thoma
Aceptado

Aquí hay algunos ejemplos mínimos completos de cómo leer archivos CSV y cómo escribir archivos CSV con Python.

Pitón puro:

import csv

# Define data
data = [
    (1, "A towel,", 1.0),
    (42, " it says, ", 2.0),
    (1337, "is about the most ", -1),
    (0, "massively useful thing ", 123),
    (-2, "an interstellar hitchhiker can have.", 3),
]

# Write CSV file
with open("test.csv", "wt") as fp:
    writer = csv.writer(fp, delimiter=",")
    # writer.writerow(["your", "header", "foo"])  # write header
    writer.writerows(data)

# Read CSV file
with open("test.csv") as fp:
    reader = csv.reader(fp, delimiter=",", quotechar='"')
    # next(reader, None)  # skip the headers
    data_read = [row for row in reader]

print(data_read)

Después de eso, el contenido de data_readson

[['1', 'A towel,', '1.0'],
 ['42', ' it says, ', '2.0'],
 ['1337', 'is about the most ', '-1'],
 ['0', 'massively useful thing ', '123'],
 ['-2', 'an interstellar hitchhiker can have.', '3']]

Tenga en cuenta que CSV solo lee cadenas. Debe convertir manualmente a los tipos de columnas.

Antes había una versión de Python 2+3 ( enlace ), pero se eliminó la compatibilidad con Python 2 . Eliminar el material de Python 2 simplificó enormemente esta respuesta.

Relacionado

  • ¿Cómo escribo datos en formato csv como cadena (no como archivo)?
  • ¿Cómo puedo usar io.StringIO() con el módulo csv? : Esto es interesante si desea servir un CSV sobre la marcha con Flask, sin almacenar el CSV en el servidor.

mpu

Echa un vistazo a mi paquete de utilidades mpupara encontrar uno súper simple y fácil de recordar:

import mpu.io
data = mpu.io.read('example.csv', delimiter=',', quotechar='"', skiprows=None)
mpu.io.write('example.csv', data)

pandas

import pandas as pd

# Read the CSV into a pandas data frame (df)
#   With a df you can do many things
#   most important: visualize data with Seaborn
df = pd.read_csv('myfile.csv', sep=',')
print(df)

# Or export it in many ways, e.g. a list of tuples
tuples = [tuple(x) for x in df.values]

# or export it as a list of dicts
dicts = df.to_dict().values()

Consulte read_csvlos documentos para obtener más información. Tenga en cuenta que pandas infiere automáticamente si hay una línea de encabezado, pero también puede configurarla manualmente.

Si no has oído hablar de Seaborn , te recomiendo que le eches un vistazo.

Otro

La lectura de archivos CSV es compatible con muchas otras bibliotecas, por ejemplo:

  • dask.dataframe.read_csv
  • spark.read.csv

Archivo CSV creado

1,"A towel,",1.0
42," it says, ",2.0
1337,is about the most ,-1
0,massively useful thing ,123
-2,an interstellar hitchhiker can have.,3

Terminaciones de archivos comunes

.csv

Trabajando con los datos

Después de leer el archivo CSV en una lista de tuplas/dictados o un marco de datos de Pandas, simplemente está trabajando con este tipo de datos. Nada específico de CSV.

Alternativas

  • JSON: Agradable para escribir datos legibles por humanos; MUY comúnmente utilizado ( lectura y escritura )
  • CSV: formato súper simple ( lectura y escritura )
  • YAML: agradable de leer, similar a JSON ( lectura y escritura )
  • pickle: un formato de serialización de Python ( lectura y escritura )
  • MessagePack ( paquete Python ): representación más compacta ( lectura y escritura )
  • HDF5 ( paquete Python ): ideal para matrices ( lectura y escritura )
  • XML: también existe *suspiro* ( lectura y escritura )

Para su aplicación, lo siguiente puede ser importante:

  • Soporte por otros lenguajes de programación.
  • Rendimiento en lectura/escritura
  • Compacidad (tamaño de archivo)

Ver también: Comparación de formatos de serialización de datos

En caso de que esté buscando una forma de crear archivos de configuración, es posible que desee leer mi breve artículo Archivos de configuración en Python.

Martin Thoma avatar Jan 11 '2017 07:01 Martin Thoma

Si es necesario, lea un archivo csv sin utilizar el módulo csv:

rows = []
with open('test.csv') as f:
    for line in f:
        # strip whitespace
        line = line.strip()
        # separate the columns
        line = line.split(',')
        # save the line for use later
        rows.append(line)
 avatar Jan 26 '2021 19:01

Si está trabajando con datos CSV y desea una solución que ocupe menos espacio que pandas, puede probar mi paquete, littletable . Puede instalarse mediante pip o simplemente colocarse como un único archivo .py con su propio código, por lo que es muy portátil y adecuado para aplicaciones sin servidor.

Leer datos CSV es tan simple como llamar csv_import:

data = """\
1,"A towel,",1.0
42," it says, ",2.0
1337,is about the most ,-1
0,massively useful thing ,123
-2,an interstellar hitchhiker can have.,3"""

import littletable as lt
tbl = lt.Table().csv_import(data, fieldnames="number1,words,number2".split(','))
tbl.present()

Huellas dactilares:

  Number1   Words                                  Number2  
 ────────────────────────────────────────────────────────── 
  1         A towel,                               1.0      
  42         it says,                              2.0      
  1337      is about the most                      -1       
  0         massively useful thing                 123      
  -2        an interstellar hitchhiker can have.   3    

( littletableutiliza el módulo enriquecido para presentar tablas).

littletableno intenta convertir automáticamente datos numéricos, por lo que se necesita una función de transformación numérica para las columnas numéricas.

def get_numeric(s):
    try:
        return int(s)
    except ValueError:
        try:
            return float(s)
        except ValueError:
            return s

tbl = lt.Table().csv_import(
    data,
    fieldnames="number1,words,number2".split(','),
    transforms={}.fromkeys("number1 number2".split(), get_numeric)
)
tbl.present()

Esto da:

  Number1   Words                                  Number2  
 ────────────────────────────────────────────────────────── 
        1   A towel,                                   1.0  
       42    it says,                                  2.0  
     1337   is about the most                           -1  
        0   massively useful thing                     123  
       -2   an interstellar hitchhiker can have.         3  

Las columnas numéricas están justificadas a la derecha en lugar de a la izquierda.

littletabletambién tiene otras características ORM-ish, como indexación, unión, pivotación y búsqueda de texto completo. Aquí hay una tabla de estadísticas sobre las columnas numéricas:

tbl.stats("number1 number2".split()).present()

  Name       Mean   Min    Max   Variance              Std_Dev   Count   Missing  
 ──────────────────────────────────────────────────────────────────────────────── 
  number1   275.6    -2   1337   352390.3    593.6247130974249       5         0  
  number2    25.6    -1    123     2966.8   54.468339427597755       5         0  

o transpuesto:

tbl.stats("number1 number2".split(), by_field=False).present()

  Stat                 Number1              Number2 
 ─────────────────────────────────────────────────── 
  mean                   275.6                 25.6
  min                       -2                   -1
  max                     1337                  123
  variance            352390.3               2966.8
  std_dev    593.6247130974249   54.468339427597755
  count                      5                    5
  missing                    0                    0

También se pueden generar otros formatos, como Markdown:

print(tbl.stats("number1 number2".split(), by_field=False).as_markdown())

| stat | number1 | number2 |
|---|---:|---:|
| mean | 275.6 | 25.6 |
| min | -2 | -1 |
| max | 1337 | 123 |
| variance | 352390.3 | 2966.8 |
| std_dev | 593.6247130974249 | 54.468339427597755 |
| count | 5 | 5 |
| missing | 0 | 0 |

Lo que se renderizaría desde Markdown como

estadística numero 1 Número 2
significar 275,6 25.6
mín. -2 -1
máximo 1337 123
diferencia 352390.3 2966,8
std_dev 593.6247130974249 54.468339427597755
contar 5 5
desaparecido 0 0

Por último, aquí hay una búsqueda de texto sobre las palabras para cualquier entrada con la palabra "autoestopista":

tbl.create_search_index("words")
for match in tbl.search.words("hitchhiker"):
    print(match)

Huellas dactilares:

   namespace(number1=-2, words='an interstellar hitchhiker can have.', number2=3)
PaulMcG avatar Feb 21 '2022 22:02 PaulMcG

Escribir un archivo CSV

Primero necesitas importar csv

Por ejemplo:

import csv

with open('eggs.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=' ',
                        quotechar='|', quoting=csv.QUOTE_MINIMAL)
    spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
    spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
Syed Abdul Rehman avatar Jan 11 '2017 07:01 Syed Abdul Rehman