Librería Pandas Python
Librería Pandas Python
HTML
Leyendo contenido HTML
Advertencia
Nos animamos a que lea las trampas HTML tabla de análisis sintáctico por debajo con respecto a las
cuestiones relacionadas con los / html5lib / LXML analizadores BeautifulSoup4.
La read_html()función de nivel superior puede aceptar una cadena / archivo / URL HTML y
analizará las tablas HTML en la lista de pandas DataFrames. Veamos algunos ejemplos.
Nota
In [298]: dfs
Out[298]:
[ Bank Name City ST CERT Acquiring
Institution Closing Date
0 The First State Bank Barboursville WV 14361
MVB Bank, Inc. April 3, 2020
1 Ericson State Bank Ericson NE 18265 Farmers and
Merchants Bank February 14, 2020
2 City National Bank of New Jersey Newark NJ 21111
Industrial Bank November 1, 2019
3 Resolute Bank Maumee OH 58317
Buckeye State Bank October 25, 2019
4 Louisa Community Bank Louisa KY 58112 Kentucky Farmers Bank
Corporation October 25, 2019
.. ... ... .. ...
... ...
556 Superior Bank, FSB Hinsdale IL 32646 Superior
Federal, FSB July 27, 2001
557 Malta National Bank Malta OH 6629 North
Valley Bank May 3, 2001
558 First Alliance Bank & Trust Co. Manchester NH 34264 Southern New Hampshire
Bank & Trust February 2, 2001
559 National State Bank of Metropolis Metropolis IL 3815 Banterra
Bank of Marion December 14, 2000
560 Bank of Honolulu Honolulu HI 21029 Bank
of the Orient October 13, 2000
Nota
Los datos de la URL anterior cambian todos los lunes, por lo que los datos resultantes anteriores y los
siguientes pueden ser ligeramente diferentes.
Lea el contenido del archivo de la URL anterior y páselo read_html como una cadena:
In [300]: dfs
Out[300]:
[ Bank Name City ST ...
Acquiring Institution Closing Date Updated Date
0 Banks of Wisconsin d/b/a Bank of Kenosha Kenosha WI ... North
Shore Bank, FSB May 31, 2013 May 31, 2013
1 Central Arizona Bank Scottsdale AZ ...
Western State Bank May 14, 2013 May 20, 2013
2 Sunrise Bank Valdosta GA ...
Synovus Bank May 10, 2013 May 21, 2013
3 Pisgah Community Bank Asheville NC ...
Capital Bank, N.A. May 10, 2013 May 14, 2013
4 Douglas County Bank Douglasville GA ...
Hamilton State Bank April 26, 2013 May 16, 2013
.. ... ... .. ...
... ... ...
500 Superior Bank, FSB Hinsdale IL ...
Superior Federal, FSB July 27, 2001 June 5, 2012
501 Malta National Bank Malta OH ...
North Valley Bank May 3, 2001 November 18, 2002
502 First Alliance Bank & Trust Co. Manchester NH ... Southern New
Hampshire Bank & Trust February 2, 2001 February 18, 2003
503 National State Bank of Metropolis Metropolis IL ...
Banterra Bank of Marion December 14, 2000 March 17, 2005
504 Bank of Honolulu Honolulu HI ...
Bank of the Orient October 13, 2000 March 17, 2005
In [303]: dfs
Out[303]:
[ Bank Name City ST ...
Acquiring Institution Closing Date Updated Date
0 Banks of Wisconsin d/b/a Bank of Kenosha Kenosha WI ... North
Shore Bank, FSB May 31, 2013 May 31, 2013
1 Central Arizona Bank Scottsdale AZ ...
Western State Bank May 14, 2013 May 20, 2013
2 Sunrise Bank Valdosta GA ...
Synovus Bank May 10, 2013 May 21, 2013
3 Pisgah Community Bank Asheville NC ...
Capital Bank, N.A. May 10, 2013 May 14, 2013
4 Douglas County Bank Douglasville GA ...
Hamilton State Bank April 26, 2013 May 16, 2013
.. ... ... .. ...
... ... ...
500 Superior Bank, FSB Hinsdale IL ...
Superior Federal, FSB July 27, 2001 June 5, 2012
501 Malta National Bank Malta OH ...
North Valley Bank May 3, 2001 November 18, 2002
502 First Alliance Bank & Trust Co. Manchester NH ... Southern New
Hampshire Bank & Trust February 2, 2001 February 18, 2003
503 National State Bank of Metropolis Metropolis IL ...
Banterra Bank of Marion December 14, 2000 March 17, 2005
504 Bank of Honolulu Honolulu HI ...
Bank of the Orient October 13, 2000 March 17, 2005
El evaluador de IPython no ejecuta los siguientes ejemplos debido al hecho de que tener tantas
funciones de acceso a la red ralentiza la compilación de la documentación. Si ve un error o un ejemplo
que no se ejecuta, no dude en informarlo en la página de problemas de pandas GitHub .
Lea una URL y haga coincidir una tabla que contenga texto específico:
Especifique un número de filas para omitir usando una lista ( xrange(Python 2 también funciona
también):
Especificar convertidores para columnas. Esto es útil para datos de texto numéricos que tienen ceros a
la izquierda. Por defecto, las columnas que son numéricas se convierten en tipos numéricos y los ceros
iniciales se pierden. Para evitar esto, podemos convertir estas columnas en cadenas.
url_mcc = 'https://en.wikipedia.org/wiki/Mobile_country_code'
dfs = pd.read_html(url_mcc, match='Telekom Albania', header=0,
converters={'MNC': str})
df = pd.DataFrame(np.random.randn(2, 2))
s = df.to_html(float_format='{0:.40g}'.format)
dfin = pd.read_html(s, index_col=0)
Sin embargo, si tiene instalado bs4 y html5lib y lo aprueba Noneo lo más probable es que el análisis
tenga éxito. Tenga en cuenta que tan pronto como un análisis tenga éxito, la función volverá .
['lxml', 'bs4']
Nota
In [305]: df
Out[305]:
0 1
0 -0.184744 0.496971
1 -0.856240 1.857977
HTML:
00 1
0 - 0.49697
0 0,184744 1
1 - 1.85797
00 1
0.856240 7
El columnsargumento limitará las columnas que se muestran:
In [307]: print(df.to_html(columns=[0]))
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>0</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>-0.184744</td>
</tr>
<tr>
<th>1</th>
<td>-0.856240</td>
</tr>
</tbody>
</table>
HTML:
00
0 -
0 0,184744
-
1
0.856240
float_format toma un Python invocable para controlar la precisión de los valores de coma flotante:
In [308]: print(df.to_html(float_format='{0:.10f}'.format))
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>0</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>-0.1847438576</td>
<td>0.4969711327</td>
</tr>
<tr>
<th>1</th>
<td>-0.8562396763</td>
<td>1.8579766508</td>
</tr>
</tbody>
</table>
HTML:
00 1
0 - 0.496971132
0 0.1847438576 7
- 1.857976650
1
0.8562396763 8
bold_rows hará que las etiquetas de fila estén en negrita de forma predeterminada, pero puede
desactivarlo:
In [309]: print(df.to_html(bold_rows=False))
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>0</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>-0.184744</td>
<td>0.496971</td>
</tr>
<tr>
<td>1</td>
<td>-0.856240</td>
<td>1.857977</td>
</tr>
</tbody>
</table>
00 1
0 - 0.49697
0 0,184744 1
- 1.85797
1
0.856240 7
El classesargumento proporciona la capacidad de dar las clases CSS de la tabla HTML
resultante. Tenga en cuenta que estas clases se agregan a la 'dataframe'clase existente .
In [312]: print(url_df.to_html(render_links=True))
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>name</th>
<th>url</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>Python</td>
<td><a href="https://www.python.org/"
target="_blank">https://www.python.org/</a></td>
</tr>
<tr>
<th>1</th>
<td>Pandas</td>
<td><a href="https://pandas.pydata.org"
target="_blank">https://pandas.pydata.org</a></td>
</tr>
</tbody>
</table>
HTML:
nombre url
0
Pitón https://www.python.org/
0
https://pandas.pydata.or
1 Pandas
g
Finalmente, el escapeargumento le permite controlar si los caracteres "<", ">" y "&" escaparon en el
HTML resultante (por defecto lo es True). Entonces, para obtener el HTML sin pasar caracteres
escapadosescape=False
Escapado:
In [314]: print(df.to_html())
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>a</th>
<th>b</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>&</td>
<td>-0.474063</td>
</tr>
<tr>
<th>1</th>
<td><</td>
<td>-0.230305</td>
</tr>
<tr>
<th>2</th>
<td>></td>
<td>-0.400654</td>
</tr>
</tbody>
</table>
una si
0 -
Y
0 0,474063
-
1 <
0,230305
-
2 >
0.400654
No escapó:
In [315]: print(df.to_html(escape=False))
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>a</th>
<th>b</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>&</td>
<td>-0.474063</td>
</tr>
<tr>
<th>1</th>
<td><</td>
<td>-0.230305</td>
</tr>
<tr>
<th>2</th>
<td>></td>
<td>-0.400654</td>
</tr>
</tbody>
</table>
una si
0 -
Y
0 0,474063
-
1 <
0,230305
-
2 >
0.400654
Nota
Es posible que algunos navegadores no muestren una diferencia en la representación de las dos tablas
HTML anteriores.
Problemas con lxml
Beneficios
o lxml es muy rápido.
o lxml requiere que Cython se instale correctamente.
Inconvenientes
o lxml qué no hace ninguna garantía sobre los resultados de su análisis sintáctico a menos
que se le da margen de beneficio estrictamente válida .
o En vista de lo anterior, hemos optado por permitirle a usted, el usuario, usar
el backend lxml , pero este backend usará html5lib si lxml no se analiza
o Por lo tanto, se recomienda encarecidamente que instale BeautifulSoup4 y html5lib ,
de modo que todavía obtenga un resultado válido (siempre que todo lo demás sea
válido) incluso si lxml falla.
Problemas con BeautifulSoup4 usando lxml como backend
Beneficios
o html5lib es mucho más indulgente que lxml y, en consecuencia, trata
el marcado de la vida real de una manera mucho más sensata que simplemente,
por ejemplo, soltar un elemento sin notificarte.
o html5lib genera automáticamente un marcado HTML5 válido a partir de un
marcado no válido . Esto es extremadamente importante para analizar tablas
HTML, ya que garantiza un documento válido. Sin embargo, eso NO significa
que sea "correcto", ya que el proceso de corregir el marcado no tiene una sola
definición.
o html5lib es Python puro y no requiere pasos de compilación adicionales más allá
de su propia instalación.
Inconvenientes
o El mayor inconveniente de usar html5lib es que es lento como la melaza. Sin embargo,
considere el hecho de que muchas tablas en la web no son lo suficientemente grandes
como para que el tiempo de ejecución del algoritmo de análisis importe. Es más
probable que el cuello de botella esté en el proceso de leer el texto sin formato de la
URL en la web, es decir, IO (entrada-salida). Para tablas muy grandes, esto podría no
ser cierto.
Archivos de Excel
El read_excel()método puede leer .xlsarchivos Excel 2003 ( ) utilizando el xlrdmódulo
Python. Los .xlsxarchivos de Excel 2007+ ( ) se pueden leer
usando xlrdo openpyxl. Los .xlsbarchivos binarios de Excel ( ) se pueden leer
usando pyxlsb. El to_excel()método de instancia se usa para guardar un DataFramearchivo en
Excel. En general, la semántica es similar a trabajar con datos csv . Vea el libro de cocina para algunas
estrategias avanzadas.
# Returns a DataFrame
pd.read_excel('path_to_file.xls', sheet_name='Sheet1')
ExcelFileclase
Para facilitar el trabajo con varias hojas del mismo archivo, la ExcelFile clase se puede usar para
envolver el archivo y se puede pasar a. read_excel Habrá un beneficio de rendimiento para leer
varias hojas ya que el archivo se lee en la memoria solo una vez.
xlsx = pd.ExcelFile('path_to_file.xls')
df = pd.read_excel(xlsx, 'Sheet1')
El caso de uso principal para un ExcelFilees analizar varias hojas con diferentes parámetros:
data = {}
# For when Sheet1's format differs from Sheet2
with pd.ExcelFile('path_to_file.xls') as xls:
data['Sheet1'] = pd.read_excel(xls, 'Sheet1', index_col=None,
na_values=['NA'])
data['Sheet2'] = pd.read_excel(xls, 'Sheet2', index_col=1)
Tenga en cuenta que si se utilizan los mismos parámetros de análisis para todas las hojas, simplemente
se puede pasar una lista de nombres de hoja read_excelsin pérdida de rendimiento.
Especificando hojas
Nota
Nota
# Returns a DataFrame
pd.read_excel('path_to_file.xls', 0, index_col=None, na_values=['NA'])
# Returns a DataFrame
pd.read_excel('path_to_file.xls')
Leyendo un MultiIndex
read_excelpuede leer un MultiIndexíndice, pasando una lista de columnas a index_col y
una MultiIndexcolumna pasando una lista de filas a header. Si los nombres de los niveles son
serializados index o columnsse leerán también especificando las filas / columnas que componen los
niveles.
In [317]: df.to_excel('path_to_file.xlsx')
In [319]: df
Out[319]:
a b
a c 1 5
d 2 6
b c 3 7
d 4 8
Si el índice tiene nombres de nivel, también se analizarán, utilizando los mismos parámetros.
In [321]: df.to_excel('path_to_file.xlsx')
In [323]: df
Out[323]:
a b
lvl1 lvl2
a c 1 5
d 2 6
b c 3 7
d 4 8
Si el archivo fuente tiene MultiIndexíndices y columnas, las listas que especifican cada una deben
pasarse a index_coly header:
In [325]: df.to_excel('path_to_file.xlsx')
In [327]: df
Out[327]:
c1 a
c2 b d
lvl1 lvl2
a c 1 5
d 2 6
b c 3 7
d 4 8
También puede especificar un conjunto delimitado por comas de columnas y rangos de Excel como una
cadena:
pd.read_excel('path_to_file.xls', 'Sheet1', usecols='A,C:E')
Si se usecolstrata de una lista de enteros, se supone que son los índices de las columnas del archivo a
analizar.
Si se usecolstrata de una lista de cadenas, se supone que cada cadena corresponde a un nombre de
columna proporcionado por el usuario nameso inferido de la (s) fila (s) del encabezado del
documento. Esas cadenas definen qué columnas se analizarán:
Si usecolses invocable, la función invocable se evaluará con los nombres de columna, devolviendo
nombres donde se evalúa la función invocable True.
Analizando fechas
Los valores de fecha y hora normalmente se convierten automáticamente al tipo apropiado cuando se
lee el archivo de Excel. Pero si tiene una columna de cadenas que parecen fechas (pero en realidad no
están formateadas como fechas en Excel), puede usar la parse_datespalabra clave para analizar esas
cadenas en fechas y horas:
Convertidores de celdas
Es posible transformar el contenido de las celdas de Excel mediante la converters opción Por
ejemplo, para convertir una columna a booleana:
pd.read_excel('path_to_file.xls', 'Sheet1', converters={'MyBools': bool})
Esta opción maneja los valores faltantes y trata las excepciones en los convertidores como datos
faltantes. Las transformaciones se aplican celda por celda en lugar de a la columna como un todo, por
lo que no se garantiza el tipo de matriz. Por ejemplo, una columna de enteros con valores faltantes no
se puede transformar en una matriz con dtype entero, porque NaN es estrictamente flotante. Puede
enmascarar manualmente los datos faltantes para recuperar el tipo de entero:
def cfun(x):
return int(x) if x else -1
Especificaciones de tipo
Como alternativa a los convertidores, el tipo para una columna completa se puede especificar usando
la palabra clave dtype , que lleva los nombres de columnas de un mapeo de diccionario a tipos. Para
interpretar datos sin inferencia de tipos, use el tipo stro object.
df.to_excel('path_to_file.xlsx', sheet_name='Sheet1')
Nota
bio = BytesIO()
# Seek to the beginning and read to copy the workbook to a variable in memory
bio.seek(0)
workbook = bio.read()
Nota
engineEs opcional pero recomendado. La configuración del motor determina la versión del libro de
trabajo producido. La configuración engine='xlrd'producirá un libro de trabajo en formato Excel
2003 (xls). Si usa 'openpyxl'o 'xlsxwriter'producirá un libro de trabajo en formato Excel 2007
(xlsx). Si se omite, se genera un libro de trabajo con formato Excel 2007.
Para especificar qué escritor desea usar, puede pasar un argumento de palabra clave del motor
a to_excely para ExcelWriter. Los motores incorporados son:
df.to_excel('path_to_file.xlsx', sheet_name='Sheet1')
Estilo y formato
El aspecto de las hojas de cálculo de Excel creado a partir de los pandas se pueden modificar mediante
los siguientes parámetros en el DataFrame's to_excelmétodo.
# Returns a DataFrame
pd.read_excel('path_to_file.ods', engine='odf')
Nota
Actualmente, pandas solo admite la lectura de hojas de cálculo de OpenDocument. La escritura no está
implementada.
# Returns a DataFrame
pd.read_excel('path_to_file.xlsb', engine='pyxlsb')
Nota
Actualmente, pandas solo admite la lectura de archivos binarios de Excel. La escritura no está
implementada.
Portapapeles
Una forma práctica de obtener datos es usar el read_clipboard()método, que toma el contenido del
búfer del portapapeles y los pasa al read_csvmétodo. Por ejemplo, puede copiar el siguiente texto en
el portapapeles (CTRL-C en muchos sistemas operativos):
A B C
x 1 4 p
y 2 5 q
z 3 6 r
Podemos ver que recuperamos el mismo contenido, que habíamos escrito anteriormente en el
portapapeles.
Nota
Es posible que necesite instalar xclip o xsel (con PyQt5, PyQt4 o qtpy) en Linux para usar estos
métodos.
Decapado
Todos los objetos pandas están equipados con to_picklemétodos que utilizan el cPicklemódulo de
Python para guardar estructuras de datos en el disco utilizando el formato pickle.
In [328]: df
Out[328]:
c1 a
c2 b d
lvl1 lvl2
a c 1 5
d 2 6
b c 3 7
d 4 8
In [329]: df.to_pickle('foo.pkl')
In [330]: pd.read_pickle('foo.pkl')
Out[330]:
c1 a
c2 b d
lvl1 lvl2
a c 1 5
d 2 6
b c 3 7
d 4 8
Advertencia
Ver: https://docs.python.org/3/library/pickle.html
Advertencia
read_pickle() solo está garantizado compatible con versiones anteriores de pandas versión 0.20.3
El tipo de compresión puede ser un parámetro explícito o inferirse de la extensión del archivo. Si
'infer', a continuación, utilizar gzip, bz2, zip, o xzsi extremos nombre de archivo
en '.gz', '.bz2', '.zip', o '.xz', respectivamente.
In [331]: df = pd.DataFrame({
.....: 'A': np.random.randn(1000),
.....: 'B': 'foo',
.....: 'C': pd.date_range('20130101', periods=1000, freq='s')})
.....:
In [332]: df
Out[332]:
A B C
0 -0.288267 foo 2013-01-01 00:00:00
1 -0.084905 foo 2013-01-01 00:00:01
2 0.004772 foo 2013-01-01 00:00:02
3 1.382989 foo 2013-01-01 00:00:03
4 0.343635 foo 2013-01-01 00:00:04
.. ... ... ...
995 -0.220893 foo 2013-01-01 00:16:35
996 0.492996 foo 2013-01-01 00:16:36
997 -0.461625 foo 2013-01-01 00:16:37
998 1.361779 foo 2013-01-01 00:16:38
999 -1.197988 foo 2013-01-01 00:16:39
In [335]: rt
Out[335]:
A B C
0 -0.288267 foo 2013-01-01 00:00:00
1 -0.084905 foo 2013-01-01 00:00:01
2 0.004772 foo 2013-01-01 00:00:02
3 1.382989 foo 2013-01-01 00:00:03
4 0.343635 foo 2013-01-01 00:00:04
.. ... ... ...
995 -0.220893 foo 2013-01-01 00:16:35
996 0.492996 foo 2013-01-01 00:16:36
997 -0.461625 foo 2013-01-01 00:16:37
998 1.361779 foo 2013-01-01 00:16:38
999 -1.197988 foo 2013-01-01 00:16:39
In [338]: rt
Out[338]:
A B C
0 -0.288267 foo 2013-01-01 00:00:00
1 -0.084905 foo 2013-01-01 00:00:01
2 0.004772 foo 2013-01-01 00:00:02
3 1.382989 foo 2013-01-01 00:00:03
4 0.343635 foo 2013-01-01 00:00:04
.. ... ... ...
995 -0.220893 foo 2013-01-01 00:16:35
996 0.492996 foo 2013-01-01 00:16:36
997 -0.461625 foo 2013-01-01 00:16:37
998 1.361779 foo 2013-01-01 00:16:38
999 -1.197988 foo 2013-01-01 00:16:39
In [339]: df.to_pickle("data.pkl.gz")
In [340]: rt = pd.read_pickle("data.pkl.gz")
In [341]: rt
Out[341]:
A B C
0 -0.288267 foo 2013-01-01 00:00:00
1 -0.084905 foo 2013-01-01 00:00:01
2 0.004772 foo 2013-01-01 00:00:02
3 1.382989 foo 2013-01-01 00:00:03
4 0.343635 foo 2013-01-01 00:00:04
.. ... ... ...
995 -0.220893 foo 2013-01-01 00:16:35
996 0.492996 foo 2013-01-01 00:16:36
997 -0.461625 foo 2013-01-01 00:16:37
998 1.361779 foo 2013-01-01 00:16:38
999 -1.197988 foo 2013-01-01 00:16:39
In [342]: df["A"].to_pickle("s1.pkl.bz2")
In [343]: rt = pd.read_pickle("s1.pkl.bz2")
In [344]: rt
Out[344]:
0 -0.288267
1 -0.084905
2 0.004772
3 1.382989
4 0.343635
...
995 -0.220893
996 0.492996
997 -0.461625
998 1.361779
999 -1.197988
Name: A, Length: 1000, dtype: float64
msgpack
El soporte para pandas msgpackse ha eliminado en la versión 1.0.0. Se recomienda utilizar pyarrow
para la transmisión en línea de objetos de pandas.
Advertencia
In [346]: print(store)
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
Los objetos se pueden escribir en el archivo al igual que agregar pares clave-valor a un dict:
In [351]: store['df'] = df
In [352]: store
Out[352]:
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
In [356]: store
Out[356]:
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
In [357]: store.close()
In [358]: store
Out[358]:
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
In [359]: store.is_open
Out[359]: False
# Working with, and automatically closing the store using a context manager
In [360]: with pd.HDFStore('store.h5') as store:
.....: store.keys()
.....:
HDFStore por defecto no soltará las filas que faltan. Este comportamiento se puede cambiar
mediante la configuración dropna=True.
In [365]: df_with_missing
Out[365]:
col1 col2
0 0.0 1.0
1 NaN NaN
2 2.0 NaN
Formato fijo
Los ejemplos anteriores muestran el uso de almacenamiento put, que escribe el HDF5 PyTablesen
un formato de matriz fijo, denominado fixedformato. Estos tipos de tiendas no se pueden agregar
una vez escritos (aunque simplemente puede eliminarlos y volver a escribir). Tampoco
son cuestionables ; deben ser recuperados en su totalidad. Tampoco admiten marcos de datos con
nombres de columna no únicos. Las fixedtiendas de formatos ofrecen una escritura muy rápida y
una lectura ligeramente más rápida que las tabletiendas. Este formato se especifica por defecto
cuando se usa puto to_hdfo por format='fixed'o format='f'.
Advertencia
Formato de tabla
HDFStoreadmite otro PyTablesformato en disco, el table formato. Conceptualmente,
a tabletiene una forma muy similar a un DataFrame, con filas y columnas. A tablepuede agregarse
en la misma u otras sesiones. Además, se admiten operaciones de tipo de consulta y
eliminación. Este formato se especifica
mediante format='table'o format='t' hacia appendo puto to_hdf.
In [375]: store
Out[375]:
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
Nota
Claves jerárquicas
Las claves de una tienda se pueden especificar como una cadena. Estos pueden estar en un
formato de nombre de ruta jerárquico (por ejemplo foo/bar/bah), que generará una jerarquía de
sub-tiendas (o Groupsen lenguaje PyTables). Las claves se pueden especificar sin la '/' inicial
y siempre son absolutas (por ejemplo, 'foo' se refiere a '/ foo'). Las operaciones de eliminación
pueden eliminar todo en la sub-tienda y debajo , así que tenga cuidado .
In [378]: store.put('foo/bar/bah', df)
In [381]: store
Out[381]:
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
In [384]: store
Out[384]:
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
Puede recorrer la jerarquía de grupos utilizando el walkmétodo que generará una tupla para cada
clave de grupo junto con las claves relativas de su contenido.
Advertencia
Las claves jerárquicas no se pueden recuperar como acceso punteado (atributo) como se describió
anteriormente para los elementos almacenados en el nodo raíz.
In [8]: store.foo.bar.bah
AttributeError: 'HDFStore' object has no attribute 'foo'
# you can directly access the actual PyTables node but using the root node
In [9]: store.root.foo.bar.bah
Out[9]:
/foo/bar/bah (Group) ''
children := ['block0_items' (Array), 'block0_values' (Array), 'axis0' (Array), 'axis1'
(Array)]
In [386]: store['foo/bar/bah']
Out[386]:
A B C
2000-01-01 1.334065 0.521036 0.930384
2000-01-02 -1.613932 1.088104 -0.632963
2000-01-03 -0.585314 -0.275038 -0.937512
2000-01-04 0.632369 -1.249657 0.975593
2000-01-05 1.060617 -0.143682 0.218423
2000-01-06 3.050329 1.317933 -0.963725
2000-01-07 -0.539452 -0.771133 0.023751
2000-01-08 0.649464 -1.736427 0.197288
Almacenando tipos
Almacenar tipos mixtos en una tabla
Se admite el almacenamiento de datos de tipo mixto. Las cadenas se almacenan como un ancho
fijo utilizando el tamaño máximo de la columna adjunta. Los intentos posteriores de agregar
cadenas más largas generarán a ValueError.
Pasar como un parámetro para agregar establecerá un mínimo mayor para las columnas de
cadena. El almacenamiento es actualmente compatible. Para las columnas de cadena, pasar anexar
cambiará la representación predeterminada de nan en el disco (que se convierte a / desde np.nan ),
esto por defecto
es nan .min_itemsize={`values`: size}floats, strings, ints, bools, datetime64nan_rep = 'nan
'
In [388]: df_mixed.loc[df_mixed.index[3:5],
.....: ['A', 'B', 'string', 'datetime64']] = np.nan
.....:
In [391]: df_mixed1
Out[391]:
A B C string int bool datetime64
0 -0.116008 0.743946 -0.398501 string 1 True 2001-01-02
1 0.592375 -0.533097 -0.677311 string 1 True 2001-01-02
2 0.476481 -0.140850 -0.874991 string 1 True 2001-01-02
3 NaN NaN -1.167564 NaN 1 True NaT
4 NaN NaN -0.593353 NaN 1 True NaT
5 0.852727 0.463819 0.146262 string 1 True 2001-01-02
6 -1.177365 0.793644 -0.131959 string 1 True 2001-01-02
7 1.236988 0.221252 0.089012 string 1 True 2001-01-02
In [392]: df_mixed1.dtypes.value_counts()
Out[392]:
float64 2
float32 1
datetime64[ns] 1
bool 1
object 1
int64 1
dtype: int64
In [398]: store.select('df_mi')
Out[398]:
A B C
foo bar
foo one 0.667450 0.169405 -1.358046
two -0.105563 0.492195 0.076693
three 0.213685 -0.285283 -1.210529
bar one -1.408386 0.941577 -0.342447
two 0.222031 0.052607 2.093214
baz two 1.064908 1.778161 -0.913867
three -0.030004 -0.399846 -1.234765
qux one 0.081323 -0.268494 0.168016
two -0.898283 -0.218499 1.408028
three -1.267828 -0.689263 0.520995
Nota
Consultando
Consultando una mesa
selecty las deleteoperaciones tienen un criterio opcional que se puede especificar para
seleccionar / eliminar solo un subconjunto de los datos. Esto le permite a uno tener una tabla en
disco muy grande y recuperar solo una parte de los datos.
Una consulta se especifica utilizando la Termclase debajo del capó, como una expresión booleana.
=, ==, !=, >, >=, <, <=
| : o
& : y
(y ): para agrupar
Estas reglas son similares a cómo se usan las expresiones booleanas en los pandas para la
indexación.
Nota
'index >= date'
"columns = ['A', 'D']"
"columns in ['A', 'D']"
'columns = A'
'columns == A'
"~(columns = ['A', 'B'])"
'index > df.index[3] & string = "bar"'
'(index > df.index[3] & index <= df.index[6]) | string = "bar"'
"ts >= Timestamp('2012-02-01')"
"major_axis>=20130101"
El indexersestán en el lado izquierdo de la sub-expresión:
columns` major_axis`ts
Nota
string = "HolyMoly'"
store.select('df', 'index == string')
en lugar de esto
string = "HolyMoly'"
store.select('df', 'index == %s' % string)
Este último no funcionará y generará una SyntaxError.Nota que hay una comilla simple seguida de
una comilla doble en la string variable.
que se cita string.
Aquí hay unos ejemplos:
La columnspalabra clave se puede suministrar para seleccionar una lista de columnas para devolver,
esto es equivalente a pasar un 'columns=list_of_columns_to_filter' :
Nota
In [408]: dftd
Out[408]:
A B C
0 2013-01-01 2013-01-01 00:00:10 -1 days +23:59:50
1 2013-01-01 2013-01-02 00:00:10 -2 days +23:59:50
2 2013-01-01 2013-01-03 00:00:10 -3 days +23:59:50
3 2013-01-01 2013-01-04 00:00:10 -4 days +23:59:50
4 2013-01-01 2013-01-05 00:00:10 -5 days +23:59:50
5 2013-01-01 2013-01-06 00:00:10 -6 days +23:59:50
6 2013-01-01 2013-01-07 00:00:10 -7 days +23:59:50
7 2013-01-01 2013-01-08 00:00:10 -8 days +23:59:50
8 2013-01-01 2013-01-09 00:00:10 -9 days +23:59:50
9 2013-01-01 2013-01-10 00:00:10 -10 days +23:59:50
Consultar MultiIndex
La selección de a MultiIndexse puede lograr utilizando el nombre del nivel.
In [411]: df_mi.index.names
Out[411]: FrozenList(['foo', 'bar'])
In [415]: df_mi_2
Out[415]:
A B C
foo one 0.856838 1.491776 0.001283
two 0.701816 -1.097917 0.102588
three 0.661740 0.443531 0.559313
bar one -0.459055 -1.222598 -0.455304
two -0.781163 0.826204 -0.530057
baz two 0.296135 1.366810 1.073372
three -0.994957 0.755314 2.119746
qux one -2.628174 -0.089460 -0.133636
two 0.337920 -0.634027 0.421107
three 0.604303 1.053434 1.109090
# the levels are automatically included as data columns with keyword level_n
In [417]: store.select("df_mi_2", "level_0=foo and level_1=two")
Out[417]:
A B C
foo two 0.701816 -1.097917 0.102588
Indexación
Puede crear / modificar un índice para una tabla create_table_index después de que los datos ya
estén en la tabla (después y append/put operación). Se recomienda crear un índice de tabla . Esto
acelerará mucho sus consultas cuando use un selectcon la dimensión indexada como where.
Nota
Los índices se crean automáticamente en las indexables y en cualquier columna de datos que
especifique. Este comportamiento se puede desactivar pasando index=Falsea append.
In [421]: i = store.root.df.table.cols.index.index
A menudo, al agregar grandes cantidades de datos a una tienda, es útil desactivar la creación de
índice para cada anexo y luego volver a crearlo al final.
In [428]: st.get_storer('df').table
Out[428]:
/df/table (Table(20,)) ''
description := {
"index": Int64Col(shape=(), dflt=0, pos=0),
"values_block_0": Float64Col(shape=(1,), dflt=0.0, pos=1),
"B": Float64Col(shape=(), dflt=0.0, pos=2)}
byteorder := 'little'
chunkshape := (2730,)
In [430]: st.get_storer('df').table
Out[430]:
/df/table (Table(20,)) ''
description := {
"index": Int64Col(shape=(), dflt=0, pos=0),
"values_block_0": Float64Col(shape=(1,), dflt=0.0, pos=1),
"B": Float64Col(shape=(), dflt=0.0, pos=2)}
byteorder := 'little'
chunkshape := (2730,)
autoindex := True
colindexes := {
"B": Index(9, full, shuffle, zlib(1)).is_csi=True}
In [431]: st.close()
In [438]: df_dc
Out[438]:
A B C string string2
2000-01-01 1.334065 0.521036 0.930384 foo cool
2000-01-02 -1.613932 1.000000 1.000000 foo cool
2000-01-03 -0.585314 1.000000 1.000000 foo cool
2000-01-04 0.632369 -1.249657 0.975593 foo cool
2000-01-05 1.060617 -0.143682 0.218423 NaN cool
2000-01-06 3.050329 1.317933 -0.963725 NaN cool
2000-01-07 -0.539452 -0.771133 0.023751 foo cool
2000-01-08 0.649464 -1.736427 0.197288 bar cool
# on-disk operations
In [439]: store.append('df_dc', df_dc, data_columns=['B', 'C', 'string', 'string2'])
# getting creative
In [441]: store.select('df_dc', 'B > 0 & C > 0 & string == foo')
Out[441]:
A B C string string2
2000-01-01 1.334065 0.521036 0.930384 foo cool
2000-01-02 -1.613932 1.000000 1.000000 foo cool
2000-01-03 -0.585314 1.000000 1.000000 foo cool
Hay una cierta degradación del rendimiento al hacer muchas columnas en columnas de datos , por
lo que corresponde al usuario designarlas. Además, no puede cambiar las columnas de datos (ni
indexables) después de la primera operación de agregar / poner (¡Por supuesto, simplemente
puede leer los datos y crear una nueva tabla!).
Iterador
Puede pasar iterator=Trueo chunksize=number_in_a_chunk hacia selecty select_as_multiplepara
devolver un iterador en los resultados. El valor predeterminado es 50,000 filas devueltas en un
fragmento.
Nota
También puede usar el iterador con el read_hdfque se abrirá, luego cerrará automáticamente la
tienda cuando termine de iterar.
for df in pd.read_hdf('store.h5', 'df', chunksize=3):
print(df)
Tenga en cuenta que la palabra clave chunksize se aplica a las filas de origen . Entonces, si está
haciendo una consulta, el tamaño de fragmento subdividirá el total de filas en la tabla y la consulta
aplicada, devolviendo un iterador en fragmentos de tamaño potencialmente desiguales.
Aquí hay una receta para generar una consulta y usarla para crear fragmentos de retorno de igual
tamaño.
In [446]: dfeq
Out[446]:
number
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
Consultas avanzadas
Seleccione una sola columna
Para recuperar una sola columna indexable o datos, utilizar el método select_column. Esto, por
ejemplo, le permitirá obtener el índice muy rápidamente. Estos devuelven un Seriesresultado,
indexado por el número de fila. Estos no aceptan actualmente el whereselector.
Seleccionar coordenadas
En ocasiones, desea obtener las coordenadas (también conocidas como ubicaciones de índice) de
su consulta. Esto devuelve una Int64Indexde las ubicaciones resultantes. Estas coordenadas
también se pueden pasar a whereoperaciones posteriores .
In [457]: c
Out[457]:
Int64Index([732, 733, 734, 735, 736, 737, 738, 739, 740, 741,
...
990, 991, 992, 993, 994, 995, 996, 997, 998, 999],
dtype='int64', length=268)
En algún momento su consulta puede implicar la creación de una lista de filas para seleccionar. Por
lo general, esto masksería el resultado indexde una operación de indexación. Este ejemplo
selecciona los meses de un índice de fecha y hora que son 5.
Objeto de almacenamiento
In [464]: store.get_storer('df_dc').nrows
Out[464]: 8
In [469]: store
Out[469]:
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
In [471]: store.select('df2_mt')
Out[471]:
C D E F foo
2000-01-01 1.602451 -0.221229 0.712403 0.465927 bar
2000-01-02 -0.525571 0.851566 -0.681308 -0.549386 bar
2000-01-03 -0.044171 1.396628 1.041242 -1.588171 bar
2000-01-04 0.463351 -0.861042 -2.192841 -1.025263 bar
2000-01-05 -1.954845 -1.712882 -0.204377 -1.608953 bar
2000-01-06 1.601542 -0.417884 -2.757922 -0.307713 bar
2000-01-07 -1.935461 1.007668 0.079529 -1.459471 bar
2000-01-08 -1.057072 -0.864360 -1.124870 1.732966 bar
# as a multiple
In [472]: store.select_as_multiple(['df1_mt', 'df2_mt'], where=['A>0', 'B>0'],
.....: selector='df1_mt')
.....:
Out[472]:
A B C D E F foo
2000-01-05 1.043605 1.798494 -1.954845 -1.712882 -0.204377 -1.608953 bar
2000-01-07 0.150568 0.754820 -1.935461 1.007668 0.079529 -1.459471 bar
Los datos se ordenan (en el disco) en términos de indexables. Aquí hay un caso de uso
simple. Usted almacena datos de tipo panel, con fechas en major_axisy ids en minor_axis. Los
datos se entrelazan así:
fecha_1
o id_1
o id_2
o .
o id_n
fecha_2
o id_1
o .
o id_n
Debe quedar claro que una operación de eliminación en el major_axisserá bastante rápida, ya que
se elimina un fragmento, luego se mueven los siguientes datos. Por otro lado, una operación de
eliminación en el minor_axisserá muy costosa. En este caso, casi con certeza sería más rápido
reescribir la tabla usando un whereque selecciona todos los datos excepto los que faltan.
Advertencia
Nota
ptrepack
PyTablesofrece un mejor rendimiento de escritura cuando las tablas se comprimen
después de que se escriben, en lugar de activar la compresión desde el principio. Puede
usar la PyTablesutilidad suministrada ptrepack. Además, ptrepackpuede cambiar los
niveles de compresión después del hecho.
Advertencias
Advertencia
Tipos de datos
HDFStoreasignará un dtype de objeto al dtype PyTablessubyacente. Esto significa que se
sabe que funcionan los siguientes tipos:
Datos categóricos
Puede escribir datos que contengan categorydtypes en a HDFStore. Las consultas
funcionan igual que si fuera una matriz de objetos. Sin embargo, los categorydatos
tipificados se almacenan de manera más eficiente.
In [474]: dfcat
Out[474]:
A B
0 a 0.477849
1 a 0.283128
2 b -2.045700
3 b -0.338206
4 c -0.423113
5 d 2.314361
6 b -0.033100
7 a -0.965461
In [475]: dfcat.dtypes
Out[475]:
A category
B float64
dtype: object
In [479]: result
Out[479]:
A B
2 b -2.045700
3 b -0.338206
4 c -0.423113
6 b -0.033100
In [480]: result.dtypes
Out[480]:
A category
B float64
dtype: object
Columnas de cadena
min_itemsize
Nota
In [482]: dfs
Out[482]:
A B
0 foo bar
1 foo bar
2 foo bar
3 foo bar
4 foo bar
In [484]: store.get_storer('dfs').table
Out[484]:
/dfs/table (Table(5,)) ''
description := {
"index": Int64Col(shape=(), dflt=0, pos=0),
"values_block_0": StringCol(itemsize=30, shape=(2,), dflt=b'', pos=1)}
byteorder := 'little'
chunkshape := (963,)
autoindex := True
colindexes := {
"index": Index(6, medium, shuffle, zlib(1)).is_csi=False}
In [486]: store.get_storer('dfs2').table
Out[486]:
/dfs2/table (Table(5,)) ''
description := {
"index": Int64Col(shape=(), dflt=0, pos=0),
"values_block_0": StringCol(itemsize=3, shape=(1,), dflt=b'', pos=1),
"A": StringCol(itemsize=30, shape=(), dflt=b'', pos=2)}
byteorder := 'little'
chunkshape := (1598,)
autoindex := True
colindexes := {
"index": Index(6, medium, shuffle, zlib(1)).is_csi=False,
"A": Index(6, medium, shuffle, zlib(1)).is_csi=False}
nan_rep
In [488]: dfss
Out[488]:
A
0 foo
1 bar
2 nan
In [490]: store.select('dfss')
Out[490]:
A
0 foo
1 bar
2 NaN
In [492]: store.select('dfss2')
Out[492]:
A
0 foo
1 bar
2 nan
Compatibilidad externa
HDFStoreescribe tableobjetos de formato en formatos específicos adecuados para
producir viajes de ida y vuelta sin pérdidas a objetos de pandas. Por compatibilidad
externa, HDFStorepuede leer PyTablestablas de formato nativo .
In [494]: df_for_r.head()
Out[494]:
first second class
0 0.864919 0.852910 0
1 0.030579 0.412962 1
2 0.015226 0.978410 0
3 0.498512 0.686761 0
4 0.232163 0.328185 1
In [497]: store_export
Out[497]:
<class 'pandas.io.pytables.HDFStore'>
File path: export.h5
# Load values and column names for all datasets from corresponding nodes and
# insert them into one data.frame object.
library(rhdf5)
return(data)
}
Nota
Rendimiento
tablesformato viene con una penalización de rendimiento de escritura en
comparación con las fixedtiendas. El beneficio es la capacidad de agregar /
eliminar y consultar (cantidades de datos potencialmente muy grandes). Los
tiempos de escritura son generalmente más largos en comparación con las tiendas
regulares. Los tiempos de consulta pueden ser bastante rápidos, especialmente en
un eje indexado.
Puede pasar chunksize=<int>a append, especificando el tamaño de fragmento de
escritura (el valor predeterminado es 50000). Esto reducirá significativamente el
uso de memoria al escribir.
Puede pasar expectedrows=<int>al primero append, para establecer el número
TOTAL de filas que PyTablesesperará. Esto optimizará el rendimiento de lectura /
escritura.
Las filas duplicadas se pueden escribir en las tablas, pero se filtran en la selección
(con los últimos elementos seleccionados; por lo tanto, una tabla es única en pares
mayores y menores)
Se PerformanceWarninggenerará una A si está intentando almacenar tipos que
serán seleccionados por PyTables (en lugar de almacenarse como tipos
endémicos). Consulte aquí para obtener más información y algunas soluciones.
Pluma
Feather proporciona serialización en columnas binarias para marcos de datos. Está
diseñado para hacer que la lectura y escritura de marcos de datos sean eficientes, y para
facilitar el intercambio de datos entre lenguajes de análisis de datos.
Varias advertencias.
Esta es una biblioteca más nueva, y el formato, aunque estable, no garantiza que
sea compatible con versiones anteriores.
El formato NO escribirá un Index, o MultiIndexpara el DataFramey generará un
error si se proporciona uno no predeterminado. Puede .reset_index()almacenar el
índice o .reset_index(drop=True)ignorarlo.
No se admiten nombres de columna duplicados y nombres de columnas sin
cadenas
Los tipos no admitidos incluyen Periodtipos de objetos Python reales. Esto
generará un mensaje de error útil en un intento de serialización.
Ver la documentación completa .
In [499]: df
Out[499]:
a b c d e f g h
i
0 a 1 3 4.0 True a 2013-01-01 2013-01-01 00:00:00-05:00 2013-01-01
00:00:00.000000000
1 b 2 4 5.0 False b 2013-01-02 2013-01-02 00:00:00-05:00 2013-01-01
00:00:00.000000001
2 c 3 5 6.0 True c 2013-01-03 2013-01-03 00:00:00-05:00 2013-01-01
00:00:00.000000002
In [500]: df.dtypes
Out[500]:
a object
b int64
c uint8
d float64
e bool
f category
g datetime64[ns]
h datetime64[ns, US/Eastern]
i datetime64[ns]
dtype: object
In [501]: df.to_feather('example.feather')
In [503]: result
Out[503]:
a b c d e f g h
i
0 a 1 3 4.0 True a 2013-01-01 2013-01-01 00:00:00-05:00 2013-01-01
00:00:00.000000000
1 b 2 4 5.0 False b 2013-01-02 2013-01-02 00:00:00-05:00 2013-01-01
00:00:00.000000001
2 c 3 5 6.0 True c 2013-01-03 2013-01-03 00:00:00-05:00 2013-01-01
00:00:00.000000002
# we preserve dtypes
In [504]: result.dtypes
Out[504]:
a object
b int64
c uint8
d float64
e bool
f category
g datetime64[ns]
h datetime64[ns, US/Eastern]
i datetime64[ns]
dtype: object
Parquet
Nuevo en la versión 0.21.0.
Varias advertencias.
Nota
Estos motores son muy similares y deberían leer / escribir archivos de formato de parquet
casi idénticos. Actualmente pyarrowno admite datos
timedelta, fastparquet>=0.1.4admite fechas y horas con reconocimiento de zona
horaria. Estas bibliotecas difieren al tener diferentes dependencias subyacentes
( fastparquetmediante el uso numba, mientras que pyarrowutiliza una biblioteca c).
In [506]: df
Out[506]:
a b c d e f g h i
0 a 1 3 4.0 True 2013-01-01 2013-01-01 00:00:00-05:00 a a
1 b 2 4 5.0 False 2013-01-02 2013-01-02 00:00:00-05:00 b b
2 c 3 5 6.0 True 2013-01-03 2013-01-03 00:00:00-05:00 c c
In [507]: df.dtypes
Out[507]:
a object
b int64
c uint8
d float64
e bool
f datetime64[ns]
g datetime64[ns, US/Eastern]
h category
i category
dtype: object
In [512]: result.dtypes
Out[512]:
a object
b int64
c uint8
d float64
e bool
f datetime64[ns]
g datetime64[ns, US/Eastern]
h category
i category
dtype: object
Manejo de índices
Serializar un DataFrameparquet puede incluir el índice implícito como una o más columnas
en el archivo de salida. Por lo tanto, este código:
Esta columna adicional inesperada hace que algunas bases de datos como Amazon
Redshift rechacen el archivo, porque esa columna no existe en la tabla de destino.
Parquet admite la partición de datos en función de los valores de una o más columnas.
test
├── a=0
│ ├── 0bac803e32dc42ae83fddfd029cbdebc.parquet
│ └── ...
└── a=1
├── e6ab24a4f45147b49b54a662f0c412a3.parquet
└── ...
ORC
Nuevo en la versión 1.0.0.
Similar al formato de parquet , el formato ORC es una serialización columnar binaria para
marcos de datos. Está diseñado para hacer que la lectura de marcos de datos sea
eficiente. Pandas proporciona solamente un lector para el formato de
ORC, read_orc(). Esto requiere la biblioteca pyarrow .
Consultas SQL
El pandas.io.sqlmódulo proporciona una colección de contenedores de consultas para
facilitar la recuperación de datos y para reducir la dependencia de la API específica de
DB. SQLAlchemy proporciona la abstracción de la base de datos si está instalada. Además,
necesitará una biblioteca de controladores para su base de datos. Ejemplos de tales
controladores son psycopg2 para PostgreSQL o pymysql para MySQL. Para SQLite, esto
se incluye en la biblioteca estándar de Python de forma predeterminada. Puede encontrar
una descripción general de los controladores compatibles para cada dialecto SQL en
los documentos de SQLAlchemy .
Nota
Con algunas bases de datos, escribir DataFrames grandes puede provocar errores debido
a que se exceden las limitaciones de tamaño de paquete. Esto se puede evitar
configurando el chunksizeparámetro al llamar to_sql. Por ejemplo, lo siguiente
escribe dataen la base de datos en lotes de 1000 filas a la vez:
Nota
Debido al soporte limitado para timedelta's en los diferentes tipos de bases de datos, las
columnas con tipo timedelta64se escribirán como valores enteros como nanosegundos en
la base de datos y se generará una advertencia.
Nota
La siguiente tabla enumera los tipos de datos admitidos para datos de fecha y hora para
algunas bases de datos comunes. Otros dialectos de bases de datos pueden tener
diferentes tipos de datos para datos de fecha y hora.
Método de inserción
Nuevo en la versión 0.24.0.
Parameters
----------
table : pandas.io.sql.SQLTable
conn : sqlalchemy.engine.Engine or sqlalchemy.engine.Connection
keys : list of str
Column names
data_iter : Iterable that iterates the values to be inserted
"""
# gets a DBAPI connection that can provide a cursor
dbapi_conn = conn.connection
with dbapi_conn.cursor() as cur:
s_buf = StringIO()
writer = csv.writer(s_buf)
writer.writerows(data_iter)
s_buf.seek(0)
Tablas de lectura
read_sql_table() leerá una tabla de base de datos con el nombre de la tabla y,
opcionalmente, un subconjunto de columnas para leer.
Nota
Nota
Tenga en cuenta que pandas infiere tipos de columna de los resultados de la consulta y no
busca tipos de datos en el esquema físico de la base de datos. Por ejemplo, suponga
que userid es una columna entera en una tabla. Luego, intuitivamente, devolverá series
con valores enteros, mientras que devolverá series con valores de objetos (str). En
consecuencia, si el resultado de la consulta está vacío, todas las columnas resultantes se
devolverán como valor de objeto (ya que son más generales). Si prevé que su consulta a
veces generará un resultado vacío, es posible que desee escribir de forma explícita
después para garantizar la integridad de
dtype.select userid ...select cast(userid as text) ...
También puede especificar el nombre de la columna como DataFrameíndice y especificar
un subconjunto de columnas para leer.
Soporte de esquema
La lectura y escritura de diferentes esquemas se admite a través de la schema palabra clave
en las funciones read_sql_table()y to_sql(). Sin embargo, tenga en cuenta que esto
depende del sabor de la base de datos (sqlite no tiene esquemas). Por ejemplo:
Consultando
Puede consultar utilizando SQL sin formato en la read_sql_query()función. En este caso,
debe usar la variante SQL adecuada para su base de datos. Al usar SQLAlchemy, también
puede pasar construcciones de lenguaje de expresión SQLAlchemy, que son
independientes de la base de datos.
engine = create_engine('postgresql://scott:tiger@localhost:5432/mydatabase')
engine = create_engine('mysql+mysqldb://scott:tiger@localhost/foo')
engine = create_engine('oracle://scott:[email protected]:1521/sidname')
engine = create_engine('mssql+pyodbc://mydsn')
# sqlite://<nohostname>/<path>
# where <path> is relative:
engine = create_engine('sqlite:///foo.db')
Si tiene una descripción SQLAlchemy de su base de datos, puede expresar dónde las
condiciones usan expresiones SQLAlchemy
Reserva de SQLite
El uso de sqlite es compatible sin usar SQLAlchemy. Este modo requiere un adaptador de
base de datos Python que respete la API de Python DB .
import sqlite3
con = sqlite3.connect(':memory:')
Google BigQuery
Advertencia
pandas se integra con este paquete externo. si pandas-gbqestá instalado, puede usar los
métodos pandas pd.read_gbqy DataFrame.to_gbq, que llamará a las funciones respectivas
desde pandas-gbq.
Formato Stata
Escribiendo en formato stata
El método to_stata()escribirá un DataFrame en un archivo .dta. La versión de formato de
este archivo es siempre 115 (Stata 12).
In [546]: df.to_stata('stata.dta')
Nota
Advertencia
Advertencia
In [547]: pd.read_stata('stata.dta')
Out[547]:
index A B
0 0 0.608228 1.064810
1 1 -0.780506 -2.736887
2 2 0.143539 1.170191
3 3 -1.573076 0.075792
4 4 -1.722223 -0.774650
5 5 0.803627 0.221665
6 6 0.584637 0.147264
7 7 1.057825 -0.284136
8 8 0.912395 1.552808
9 9 0.189376 -0.109830
Nota
Nota
Datos categóricos
Categoricallos datos se pueden exportar a archivos de datos Stata como datos
etiquetados como valores. Los datos exportados consisten en los códigos de categoría
subyacentes como valores de datos enteros y las categorías como etiquetas de
valor. Stata no tiene un equivalente explícito a ay la Categoricalinformación sobre si la
variable está ordenada se pierde al exportar.
Advertencia
Stata solo admite etiquetas de valor de cadena, por lo que strse llama a las categorías al
exportar datos. La exportación de Categoricalvariables con categorías que no son
cadenas produce una advertencia y puede provocar una pérdida de información si
las strrepresentaciones de las categorías no son únicas.
Los datos etiquetados se pueden importar de manera similar desde los archivos de datos
de Stata como Categorical variables utilizando el argumento de la palabra
clave convert_categoricals( Truepor defecto). El argumento de la palabra
clave order_categoricals( Truepor defecto) determina si
las Categoricalvariables importadas están ordenadas.
Nota
Nota
Formatos SAS
La función de nivel superior read_sas()puede leer (pero no escribir) SAS xport (.xpt) y
(ya v0.18.0 ) SAS7BDAT archivos de formato (.sas7bdat).
Los archivos SAS solo contienen dos tipos de valores: texto ASCII y valores de coma
flotante (generalmente 8 bytes pero a veces truncados). Para los archivos xport, no hay
conversión automática de tipo a enteros, fechas o categorías. Para los archivos
SAS7BDAT, los códigos de formato pueden permitir que las variables de fecha se
conviertan automáticamente en fechas. Por defecto, todo el archivo se lee y se devuelve
como a DataFrame.
df = pd.read_sas('sas_data.sas7bdat')
def do_something(chunk):
pass
Formatos SPSS
Nuevo en la versión 0.25.0.
Los archivos SPSS contienen nombres de columna. Por defecto, se lee todo el archivo, las
columnas categóricas se convierten pd.Categoricaly DataFramese devuelve a con todas
las columnas.
df = pd.read_spss('spss_data.sav')
netCDF
xarray proporciona estructuras de datos inspiradas en los pandas DataFramepara trabajar
con conjuntos de datos multidimensionales, con un enfoque en el formato de archivo
netCDF y una fácil conversión hacia y desde los pandas.
Consideraciones de rendimiento
Esta es una comparación informal de varios métodos IO, usando pandas 0.24.2. Los
tiempos dependen de la máquina y se deben ignorar las pequeñas diferencias.
In [1]: sz = 1000000
In [2]: df = pd.DataFrame({'A': np.random.randn(sz), 'B': [1] * sz})
In [3]: df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000000 entries, 0 to 999999
Data columns (total 2 columns):
A 1000000 non-null float64
B 1000000 non-null int64
dtypes: float64(1), int64(1)
memory usage: 15.3 MB
import numpy as np
import os
sz = 1000000
df = pd.DataFrame({'A': np.random.randn(sz), 'B': [1] * sz})
sz = 1000000
np.random.seed(42)
df = pd.DataFrame({'A': np.random.randn(sz), 'B': [1] * sz})
def test_sql_write(df):
if os.path.exists('test.sql'):
os.remove('test.sql')
sql_db = sqlite3.connect('test.sql')
df.to_sql(name='test_table', con=sql_db)
sql_db.close()
def test_sql_read():
sql_db = sqlite3.connect('test.sql')
pd.read_sql_query("select * from test_table", sql_db)
sql_db.close()
def test_hdf_fixed_write(df):
df.to_hdf('test_fixed.hdf', 'test', mode='w')
def test_hdf_fixed_read():
pd.read_hdf('test_fixed.hdf', 'test')
def test_hdf_fixed_write_compress(df):
df.to_hdf('test_fixed_compress.hdf', 'test', mode='w', complib='blosc')
def test_hdf_fixed_read_compress():
pd.read_hdf('test_fixed_compress.hdf', 'test')
def test_hdf_table_write(df):
df.to_hdf('test_table.hdf', 'test', mode='w', format='table')
def test_hdf_table_read():
pd.read_hdf('test_table.hdf', 'test')
def test_hdf_table_write_compress(df):
df.to_hdf('test_table_compress.hdf', 'test', mode='w',
complib='blosc', format='table')
def test_hdf_table_read_compress():
pd.read_hdf('test_table_compress.hdf', 'test')
def test_csv_write(df):
df.to_csv('test.csv', mode='w')
def test_csv_read():
pd.read_csv('test.csv', index_col=0)
def test_feather_write(df):
df.to_feather('test.feather')
def test_feather_read():
pd.read_feather('test.feather')
def test_pickle_write(df):
df.to_pickle('test.pkl')
def test_pickle_read():
pd.read_pickle('test.pkl')
def test_pickle_write_compress(df):
df.to_pickle('test.pkl.compress', compression='xz')
def test_pickle_read_compress():
pd.read_pickle('test.pkl.compress', compression='xz')
def test_parquet_write(df):
df.to_parquet('test.parquet')
def test_parquet_read():
pd.read_parquet('test.parquet')