2012-03-15 14 views
9

? Tengo manos en pandas y estoy averiguando cómo puedo leer un archivo. El archivo es de la base de datos WRDS y la lista de componentes SP500 se remonta a la década de 1960. Revisé el archivo y no importa lo que haga para importarlo usando 'read_csv', aún no puedo mostrar los datos correctamente.¿Cómo leo un archivo de texto de formato de ancho de corrección en pandas

df = read_csv('sp500-sb.txt') 

df 

<class 'pandas.core.frame.DataFrame'> 
Int64Index: 1231 entries, 0 to 1230 
Data columns: gvkeyx      from      thru     conm 
                                        gvkey      co_conm 
...(the column names) 
dtypes: object(1) 

¿Qué significa el fragmento de salida anterior? Cualquier cosa sería útil

+2

que los pandas puede haber comido sus datos ? – hochl

+1

¿Podría mostrar las primeras líneas del archivo? –

Respuesta

7

Wes me respondió en un correo electrónico. Aclamaciones.

Este es un archivo de formato de ancho fijo (no delimitado por comas o pestañas como habitual). Me doy cuenta de que los pandas no tienen un lector de ancho fijo como R, aunque se puede configurar con mucha facilidad. Veré lo que puedo hacer. Mientras tanto, si puedes exportar los datos en otro formato (como csv, verdaderamente separados por comas) podrás leerlos con read_csv. I sospechoso con un poco de magia Unix puede transformar un archivo FWF en un archivo CSV .

recomiendo después de la emisión en github como su dirección de correo electrónico está a punto de desaparecen de mi bandeja de entrada :)

https://github.com/pydata/pandas/issues/920

mejor, Wes

+6

Sigue a la respuesta. El formato de ancho de corrección de lectura ahora se implementa mediante read_fwf(). Ver http://pandas.pydata.org/pandas-docs/dev/io.html#files-with-fixed-width-columns –

0

¿Qué quieres decir con display? ¿No le da df['gvkey'] los datos en la columna gvkey?

Si lo que hace es imprimir todo el marco de datos a la consola, entonces eche un vistazo a df.to_string(), pero será difícil de leer si tiene demasiadas columnas. Pandas no se imprimirán todo el asunto de manera predeterminada si tiene demasiadas columnas:

import pandas 
import numpy 

df1 = pandas.DataFrame(numpy.random.randn(10, 3), columns=['col%d' % d for d in range(3)]) 
df2 = pandas.DataFrame(numpy.random.randn(10, 30), columns=['col%d' % d for d in range(30)]) 

print df1 # <--- substitute by df2 to see the difference 
print 
print df1['col1'] 
print 
print df1.to_string() 
+0

gracias TR. Mi archivo de datos tiene un formato de ancho fijo ... actualmente no compatible. Wes ha agregado graciosamente a la lista de problemas de Forge for Panda. – user1234440

+0

¿Todavía tiene acceso a WRDS?Debería tener una opción allí para dar salida al archivo en formato csv. –

0

usuario, si usted necesita para hacer frente con el formato fijo en este momento, puede usar algo como lo siguiente:

def fixed_width_to_items(filename, fields, first_column_is_index=False, ignore_first_rows=0): 
    reader = open(filename, 'r') 
    # skip first rows 
    for i in xrange(ignore_first_rows): 
     reader.next() 
    if first_column_is_index: 
     index = slice(0, fields[1]) 
     fields = [slice(*x) for x in zip(fields[1:-1], fields[2:])] 
     return ((line[index], [line[x].strip() for x in fields]) for line in reader) 
    else: 
     fields = [slice(*x) for x in zip(fields[:-1], fields[1:])] 
     return ((i, [line[x].strip() for x in fields]) for i,line in enumerate(reader)) 

Aquí está en programa de est:

import pandas 
import numpy 
import tempfile 

# create a data frame 
df = pandas.DataFrame(numpy.random.randn(100, 5)) 
file_ = tempfile.NamedTemporaryFile(delete=True) 
file_.write(df.to_string()) 
file_.flush() 

# specify fields 
fields = [0, 3, 12, 22, 32, 42, 52] 
df2 = pandas.DataFrame.from_items(fixed_width_to_items(file_.name, fields, first_column_is_index=True, ignore_first_rows=1)).T 

# need to specify the datatypes, otherwise everything is a string 
df2 = pandas.DataFrame(df2, dtype=float) 
df2.index = [int(x) for x in df2.index] 

# check 
assert (df - df2).abs().max().max() < 1E-6 

Esto debe hacer el truco si lo necesita en este momento, pero hay que tener en cuenta que la función anterior es muy simple, en particular, que no hace nada acerca de los tipos de datos.

Cuestiones relacionadas