Python: ¿Cómo cargar la columna desde tablas csv multibloque?
Frecuentes
Visto 472 veces
2
Estoy trabajando en un programa apto para datos SIP en este momento. Desafortunadamente, los datos vienen dentro de una tabla csv con la siguiente estructura:
f; Abs(Zm); Std(Abs); Phi(Zm); Std(Phi); Re(Zm); Im(Zm); Time [s]
1.0000000e-001; 7712.6262; 0.0247; -0.003774; 0.000001; 7712.5713; -29.1074; 3418623040
2.0000000e-001; 7712.4351; 0.0030; -0.007543; 0.000001; 7712.2157; -58.1732; 3418623056
5.0000000e-001; 7710.8455; 0.0094; -0.018837; 0.000002; 7709.4775; -145.2434; 3418623063
1.0000000e+000; 7705.3763; 0.0098; -0.037637; 0.000000; 7699.9195; -289.9395; 3418623067
2.0000000e+000; 7683.8120; 0.0241; -0.075058; 0.000001; 7662.1778; -576.1935; 3418623069
5.0000000e+000; 7539.7945; 0.0080; -0.184724; 0.000002; 7411.5201; -1384.8720; 3418623071
1.0000000e+001; 7088.6894; 0.0060; -0.351521; 0.000001; 6655.2169; -2440.8206; 3418623072
f; Abs(Z12); Phi(Z12); Abs(Z34); Phi(Z34); Abs(Z14); Phi(Z14); Time [s]
1.0000000e-001; 1.7821; 3.139014; 0.2545; -3.141592; 7710.5896; -0.003774; 3418623040
2.0000000e-001; 1.7850; 3.133381; 0.2572; -3.126220; 7710.3930; -0.007543; 3418623056
5.0000000e-001; 1.7755; 3.121223; 0.2514; -3.133763; 7708.8186; -0.018838; 3418623063
1.0000000e+000; 1.7683; 3.100815; 0.2503; 3.139466; 7703.3580; -0.037638; 3418623067
2.0000000e+000; 1.8091; 3.058834; 0.2538; -3.123705; 7681.7502; -0.075060; 3418623069
5.0000000e+000; 1.5547; 2.943611; 0.2398; -3.136317; 7538.0045; -0.184727; 3418623071
Estoy usando una rutina numpy.loadtxt() para recopilar los datos de la tabla de esta manera:
def load_datafile(filename):
try:
x_data, y_data = numpy.loadtxt(filename , unpack=True, usecols=(0,1),)
except IOError:
print('There was an error opening the file: {0}'.format(filename))
x_data=[]
y_data=[]
return x_data, y_data
Sé que no hay más identificadores para usar un bloque específico de una tabla en el comando loadtxt(). ¿Pero hay una solución práctica?
De lo contrario, ¿hay un script simple que pueda reorganizar el archivo de entrada csv en columnas de un solo bloque?
¡Gracias por adelantado! Saludos, Gunnar
2 Respuestas
1
Primero podría dividir los datos de entrada en bloques, luego usar loadtxt o genfromtxt (prefiero este, porque tiene una opción para leer encabezados).
from numpy import genfromtxt
from StringIO import StringIO
def read_by_block(filename):
blocks = []
data = open(filename).read()
for blk in data.split('\n\n'): # we assume that blocks are separated by two newlines
blocks.append(genfromtxt(StringIO(blk), delimiter=';', names=True))
return blocks
data = read_by_block('data.txt')
print data[0].dtype.names # print fields for first block
print data[0]['StdPhi'] # print column 'Std(Phi)' in 1st block
contestado el 03 de mayo de 12 a las 13:05
Gracias por la idea de genfromtxt(). Después de manipular el estilo de nueva línea en mi tabla csv, funcionó muy bien. - usuario1371788
Si desea más flexibilidad con respecto al estilo de nueva línea, también puede dividir según la expresión regular: re.split
. - François
1
Suponiendo que, al igual que la entrada, siempre hay un par de saltos de línea vacíos, este pequeño script debería devolver un montón de objetos de archivo:
def parseMultiblockCSV(filename):
original = open(filename, "r")
newlines = 0
block = 0
current = open(filename + "." + str(block), "w")
for line in original:
if line == "":
newlines += 1
if newlines >= 2:
current.close()
block += 1
current = open(filename + "." + str(block), "w")
current.write(line)
current.close()
files = []
for n in range(block + 1):
files.append(open(filename + "." + str(n)))
return files
Si luego los necesitaba a ambos en la misma tabla, supongo que tiene una función para cargar varios archivos en una sola tabla. De lo contrario:
def combineCSVFiles(files, output):
if len(files) == 1:
return files[0]
start = file[0]
files = file[1:]
out = open(output, "w")
for line in start:
out.write(line)
for input in files:
first = false
for line in input:
if not first:
first = true
continue
out.write(line)
out.close()
return open(output, "r")
Eso debería devolver un objeto de archivo que contenga los contenidos concatenados de los objetos de archivo dados, ignorando la primera línea de encabezado de cualquier cosa que no sea el primer archivo.
contestado el 03 de mayo de 12 a las 08:05
Creo que las columnas son diferentes de un bloque a otro, por lo que su respuesta no maneja eso. ¿O me pierdo algo? - bmu
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python csv numpy block or haz tu propia pregunta.
¿Podría aclarar qué quiere decir con un "bloque"? - wim
sus datos de ejemplo tienen diferentes columnas en cada bloque y el tamaño del bloque es diferente de un bloque a otro (7 filas en el primero, 6 en el segundo). ¿Es eso cierto? ¿Necesita leer los datos de cada bloque y cada columna? - bmu