En la entrada anterior vimos la clase Series de Pandas, que representa vectores de datos y se asemeja a una columna de una hoja de cálculo de Excel. Siguiendo con esa analogía, la clase DataFrame representa una hoja de cálculo completa, en la que cada columna es un objeto Series.
Los objetos Series que forman un DataFrame comparten un único índice (igual que las columnas de una hoja de cálculo), y cada uno tiene un nombre único.
>>> import pandas as pd >>> idx = range(5) >>> cols = ['A','B','C'] >>> d = pd.DataFrame(index=idx, columns=cols) >>> print(d) A B C 0 NaN NaN NaN 1 NaN NaN NaN 2 NaN NaN NaN 3 NaN NaN NaN 4 NaN NaN NaN
Dado que el DataFrame está vacío, todas las entradas aparecen como NaN (Not a Number). Rellenaremos el objeto con datos para ver cómo se pueden direccionar los contenidos de un DataFrame. Por ejemplo, podemos acceder a un elemento individual usando su valore de índice y columna:
>>> d.loc[0,'A'] = 'Hello' >>> print(d) A B C 0 Hello NaN NaN 1 NaN NaN NaN 2 NaN NaN NaN 3 NaN NaN NaN 4 NaN NaN NaN
Hay otros métodos para hacer esto, pero usaremos siempre DataFrame.loc[] por simplicidad. Por esto mismo, en la entrada sobre el objeto Series recomendé el uso de Series.loc[] para acceder a los elementos.
Podemos seleccionar una columna completa, o un rango de valores.
>>> d.loc[:,'B'] = 'Column B' #Establece el valor de todos los elementos de la columna B >>> d.loc[1:4,'A'] = 'A' #Establece el valor de los índices 1 a 4 de la columna A >>> print(d) A B C 0 Hello Column B NaN 1 A Column B NaN 2 A Column B NaN 3 A Column B NaN 4 A Column B NaN
El operador : funciona de forma similar a los slices de listas de Python. Resumiendo: para seleccionar la columna completa, se debe usar el operador : como rango del índice; y para seleccionar un subconjunto de los valores de la columna, [inicio]:[fin] (teniendo en cuenta que, a diferencia de los slices, [fin] sí estaría incluido entre los datos seleccionados).
Del mismo modo, podemos direccionar las filas:
>>> d.loc[1,:] = 'NO INFO' >>> print(d) A B C 0 Hello Column B NaN 1 NO INFO NO INFO NO INFO 2 A Column B NaN 3 A Column B NaN 4 A Column B NaN
Cuando usamos el operador DataFrame.loc[], nos devuelve una referencia en forma de Series o DataFrame (dependiendo de si ambos índices están dados como rangos). Por tanto, todas las operaciones que se introdujeron para las Series pueden usarse sobre el resultados de la llamada:
>>> d.loc[:,'A'].apply(len) 0 5 1 7 2 1 3 1 4 1 Name: A, dtype: int64
Este ejemplo aplica la función len a cada cadena de la columna A. Devuelve un objeto Series con la longitud de cada entrada. El método apply() también se puede aplicar a un DataFrame. En lugar de funcionar elemento a elemento, actúa sobre cada columna o fila (dependiendo del parámetro axis):
>>> d.apply(len) A 5 B 5 C 5 dtype: int64 >>> d.apply(len, axis=1) 0 3 1 3 2 3 3 3 4 3 dtype: int64
Para aplicar una función elemento a elemento, se usa el método DataFrame.applymap():
>>> d.applymap(type) A B C 01 2 3 4
De forma similar a como pasa en Series, podemos filtrar las columnas/filas según una condición. Por ejemplo, podemos elegir las filas que cumplen una determinada condición en la columna A:
>>> d.loc[d.loc[:,'A']!='A',:] A B C 0 Hello Column B NaN 1 NO INFO NO INFO NO INFO
Aquí, la expresión d.loc[:,’A’]!=’A’ se usa para indexar las filas. Por sí misma, esta expresión produce el siguiente resultado:
>>> d.loc[d.loc[:,'A']!='A',:] 0 True 1 True 2 False 3 False 4 False Name: A, dtype: bool
Se obtiene un Series que actúa como máscara del índice de d, indicando qué filas cumplen la condición.
Con esto, hemos visto cómo crear un DataFrame y cómo acceder a sus datos y operar con ellos. Hay muchas otras aplicaciones que podemos dar a los DataFrames, especialmente en el campo matemático, que iremos viendo en entradas futuras.
Muy útil.
Gracias!