[Python-es] Leer ultima linea de fichero CSV?

Chema Cortes pych3m4 en gmail.com
Lun Jul 22 15:23:31 CEST 2013


El día 22 de julio de 2013 00:05, Xavi <jarabal en gmail.com> escribió:
> Hola,
>
> Si el fichero es grande, procesarlo en su totalidad es un gasto innecesario
> de tiempo y recursos.
>
>> ... puedes usar deque (en el módulo collections) ...
>
>
> Me temo que deque sigue procesando todo el fichero, descartando todas las
> lineas menos las n (maxlen) últimas.
> Creo que la única manera de asegurarse que sólo se procesan los últimos
> MAX_READ bytes sería .-
>
> #!/usr/bin/env python3
> # -*- coding: utf-8 -*-
>
> import io
> import csv
>
> MAX_READ = 512
> with open('data.csv', 'rb') as f:
>     size = f.seek(0, 2)
>     f.seek(-MAX_READ if size > MAX_READ else -size, 2)
>     # Solo procesa MAX_READ bytes
>     lastLine = str(list(f)[-1], 'utf-8')
>     row = next(csv.reader(io.StringIO(lastLine)))
>     print('Temperatura, {}, Humedad: {}, Presión: {}'.format(row[0], row[1],
> row[2]))
>

Este código puede no ser portable. El método seek relativo al final
del fichero no siempre funciona en todas las plataformas. Sería mejor
que el segundo seek fuera relativo al principio del fichero:

f.seek(max(0, size-MAX_READ))

Por otro lado, el csv.reader puede usarse con cualquier iterador, por
lo que no es necesario usar el io.StringIO. Si lo juntamos todo,
incluyendo el "deck" (deque):

import csv
from collections import deque

with open('data.csv', 'rb', buffering=0) as f:
    size = f.seek(0,2)
    f.seek(max(0, size-MAX_READ=512))
    temperatura, humedad, presion = next(csv.reader( str(line,
'utf-8') for line in deque(f,1) ) )
    print('Temperatura, {}, Humedad: {}, Presión:
{}'.format(temperatura, humedad, presion))


Por lo general, el uso de "deque" para obtener la última línea de un
fichero es portable, además de ser bastante rápido (a la velocidad de
C).


> Un saludo
> --
> Xavi
>
> El 21/07/2013 16:12, Kiko escribió:
>>
>>
>> 2013/7/21 Juan <htpc.casa en gmail.com <mailto:htpc.casa en gmail.com>>
>>
>>
>>     Hola, quiero leer solo la ultima linea de un fichero CSV (solo la
>> linea que
>>     se actualizo por ultima vez) y no tengo claro cual sería la mejor
>> solución,
>>     este es el código actual:
>>
>>     #--------------------------------
>>     # leer fichero CSV
>>     #--------------------------------
>>     def leer_datos():
>>              y =0
>>              lectura = csv.reader(open("data.csv",
>>              for index,row in enumerate(lectura)
>>                      y +=1
>>              print 'Linea: ' + str(linea + 1)
>>              print 'Temperatura' + row[0] + ', Humedad: ' + row[1] + ',
>> presion: ' + row[2]
>>
>>       gracias
>>
>>
>> Hola, puedes usar deque (en el módulo collections) para simular un uso
>> parecido al tail de algunos sistemas operativos:
>>
>> http://docs.python.org/2/library/collections.html#deque-recipes
>>
>> Lo siguiente funciona pensando que tu fichero csv tiene 3 columnas y está
>> separado por comas. La función te devuelve los valores
>> de cada columna como float.
>>
>> from collections import deque
>> def tail(file):
>>      kk = deque(open(file), maxlen = 1)
>>      temp,hum,pres = kk[0].split('\n')[0].split(',')
>>      return float(temp), float(hum), float(pres)
>>
>> t, h, p = tail('tufichero.csv') # t, h, p es para temperatura, humedad y
>> presión
>>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> http://mail.python.org/mailman/listinfo/python-es
> FAQ: http://python-es-faq.wikidot.com/



--
Hyperreals *R  "Quarks, bits y otras criaturas infinitesimales":
http://ch3m4.org/blog
Buscador Python Hispano: http://ch3m4.org/python-es


Más información sobre la lista de distribución Python-es