DataFrames#
Los DataFrames es de las piezas más importante de pandas y están directamente inspirados en el lenguaje de programación R. Podemos pensar en un DataFrame como un conjunto de objetos Serie unidos para compartir el mismo índice.
Crear DataFrame#
import pandas as pd
import numpy as np
from numpy.random import randint
columns= ['W', 'X', 'Y', 'Z'] # four columns
index= ['A', 'B', 'C', 'D', 'E'] # five rows
np.random.seed(42)
data = randint(-100,100,(5,4))
data
'''
array([[ 2, 79, -8, -86],
[ 6, -29, 88, -80],
[ 2, 21, -26, -13],
[ 16, -1, 3, 51],
[ 30, 49, -48, -99]])
'''
df = pd.DataFrame(data,index,columns)
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
Recolectar datos#
Coger columnas#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
df['W']
'''
A 2
B 6
C 2
D 16
E 30
Name: W, dtype: int32
'''
type(df['W'])
# pandas.core.series.Series
df[['W','Z']]
'''
W Z
A 2 -86
B 6 -80
C 2 -13
D 16 51
E 30 -99
'''
df['new'] = df['W'] + df['Y']
df
'''
W X Y Z new
A 2 79 -8 -86 -6
B 6 -29 88 -80 94
C 2 21 -26 -13 -24
D 16 -1 3 51 19
E 30 49 -48 -99 -18
'''
Borrar columna#
df
'''
W X Y Z new
A 2 79 -8 -86 -6
B 6 -29 88 -80 94
C 2 21 -26 -13 -24
D 16 -1 3 51 19
E 30 49 -48 -99 -18
'''
# axis=1 porque estamos trabajando con columnas
df.drop('new',axis=1)
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
# Los cambios no se aplican si no se reasigna la variable
df
'''
W X Y Z new
A 2 79 -8 -86 -6
B 6 -29 88 -80 94
C 2 21 -26 -13 -24
D 16 -1 3 51 19
E 30 49 -48 -99 -18
'''
new_df = df.drop('new',axis=1)
new_df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
Coger fila#
Usando nombre#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
df.loc['A']
'''
W 2
X 79
Y -8
Z -86
Name: A, dtype: int32
'''
df.loc[['A','C']]
'''
W X Y Z
A 2 79 -8 -86
C 2 21 -26 -13
'''
Usando índice#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
df.iloc[0]
'''
W 2
X 79
Y -8
Z -86
Name: A, dtype: int32
'''
df.iloc[0:2]
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
'''
Borrar fila#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
# axis=0 porque estamos trabajando con filas
df.drop('C',axis=0)
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
D 16 -1 3 51
E 30 49 -48 -99
'''
# No se guardan los cambios si no reasignamos el valor
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
Seleccionar subconjunto#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
df.loc[['A','C'],['W','Y']]
'''
W Y
A 2 -8
C 2 -26
'''
Condicionales#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
df>0 #Valores del dataframe >0
'''
W X Y Z
A True True False False
B True False True False
C True True False False
D True False True True
E True True False False
'''
df[df>0] #Muestra los valores del dataframe cuyo valor >0 (si no lo cumple muestra NaN)
'''
W X Y Z
A 2 79.0 NaN NaN
B 6 NaN 88.0 NaN
C 2 21.0 NaN NaN
D 16 NaN 3.0 51.0
E 30 49.0 NaN NaN
'''
df['X']>0 #Valores de la columna X cuyo valor >0
'''
A True
B False
C True
D False
E True
Name: X, dtype: bool
'''
df[df['X']>0] #Muestra valores del dataframe cuyo valor de la columna X >0
'''
W X Y Z
A 2 79 -8 -86
C 2 21 -26 -13
E 30 49 -48 -99
'''
df[df['X']>0]['Y'] #Igual que el caso anterior pero muestra sólo columna Y
'''
A -8
C -26
E -48
Name: Y, dtype: int32
'''
df[df['X']>0][['Y','Z']] #Igual que el caso anterior pero muestra sólo columnas Y Z
'''
Y Z
A -8 -86
C -26 -13
E -48 -99
'''
df[(df['W']>0) & (df['Y'] > 1)] #Muestra dataframe que cumple valor de W >0 y valor de Y >1
'''
W X Y Z
B 6 -29 88 -80
D 16 -1 3 51
'''
Otras operaciones con índices#
Resetear índice#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
df.reset_index()
'''
index W X Y Z
0 A 2 79 -8 -86
1 B 6 -29 88 -80
2 C 2 21 -26 -13
3 D 16 -1 3 51
4 E 30 49 -48 -99
'''
Reasignar índice#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
newind = 'CA NY WY OR OO'.split()
# ['CA', 'NY', 'WY', 'OR', 'OO']
df['States'] = newind
'''
W X Y Z States
A 2 79 -8 -86 CA
B 6 -29 88 -80 NY
C 2 21 -26 -13 WY
D 16 -1 3 51 OR
E 30 49 -48 -99 OO
'''
df = df.set_index('States')
'''
W X Y Z
States
CA 2 79 -8 -86
NY 6 -29 88 -80
WY 2 21 -26 -13
OR 16 -1 3 51
OO 30 49 -48 -99
'''
df.columns
# Index(['W', 'X', 'Y', 'Z'], dtype='object')
Obtener resumen del dataframe#
df
'''
W X Y Z
A 2 79 -8 -86
B 6 -29 88 -80
C 2 21 -26 -13
D 16 -1 3 51
E 30 49 -48 -99
'''
df.describe()
'''
W X Y Z
count 5.00000 5.000000 5.000000 5.000000
mean 11.20000 23.800000 1.800000 -45.400000
std 11.96662 42.109381 51.915316 63.366395
min 2.00000 -29.000000 -48.000000 -99.000000
25% 2.00000 -1.000000 -26.000000 -86.000000
50% 6.00000 21.000000 -8.000000 -80.000000
75% 16.00000 49.000000 3.000000 -13.000000
max 30.00000 79.000000 88.000000 51.000000
'''
df.dtypes
'''
W int32
X int32
Y int32
Z int32
dtype: object
'''
df.info()
'''
<class 'pandas.core.frame.DataFrame'>
Index: 5 entries, CA to OO
Data columns (total 4 columns):
W 5 non-null int32
X 5 non-null int32
Y 5 non-null int32
Z 5 non-null int32
dtypes: int32(4)
memory usage: 120.0+ bytes
'''
Celdas sin definir#
Podemos encontrarnos en un escenario donde un dataframe no tenga algunas celdas definidas, para estos casos tenemos 3 opciones para trabajar con dichas celdas:
- Dejar la celda sin definir.
- Eliminar las celdas sin definir.
- Sobreescribir las celdas sin definir.
df = pd.DataFrame({'A':[1,2,np.nan,4],
'B':[5,np.nan,np.nan,8],
'C':[10,20,30,40]})
# 1. Dejar celdas sin definir
df
'''
A B C
0 1.0 5.0 10
1 2.0 NaN 20
2 NaN NaN 30
3 4.0 8.0 40
'''
# 2. Eliminar las celdas sin definir.
df.dropna() # Elimina todas las filas/columnas que tengan al menos un valor sin definir.
'''
A B C
0 1.0 5.0 10
3 4.0 8.0 40
'''
df.dropna(axis=1) # Elimina todas las columnas que tengan al menos un valor sin definir.
'''
C
0 10
1 20
2 30
3 40
'''
df.dropna(thresh=2) # Elimina todas las filas/columnas que tengan al menos 2 valor sin definir.
'''
A B C
0 1.0 5.0 10
1 2.0 NaN 20
3 4.0 8.0 40
'''
# 3. Sobreescribir las celdas sin definir.
df.fillna(value='FILL VALUE') # Este comando no sobrescribe el dataframe original.
'''
A B C
0 1 5 10
1 2 FILL VALUE 20
2 FILL VALUE FILL VALUE 30
3 4 8 40
'''
df['A'].fillna(value=0) # Modificar sólo columna A.
'''
0 1.0
1 2.0
2 0.0
3 4.0
Name: A, dtype: float64
'''
df.fillna(df.mean()) # Modificar celdas sin definir por la media de cada columna.
'''
A B C
0 1.000000 5.0 10
1 2.000000 6.5 20
2 2.333333 6.5 30
3 4.000000 8.0 40
'''
Agrupar valores#
Podemos encontrarnos con tablas que tengan valores en común, por ejemplo una tabla con información de alumnos, con una columna que especifique el año de nacimiento, y queremos agrupar los alumnos por el año de nacimiento. Usando agrupaciones podemos sacar datos de grupos de alumnos que tengan el mismo año de nacimiento.
df
'''
Col1 Col2
0 A 4
1 B 3
2 A 6
3 C 2
4 C 1
'''
df.groupby('Col1').sum() # Sumar valores agrupados por Col1
'''
Col2
Col1
A 10
B 3
C 3
'''
También se pueden crear grupos usando más de una key.
df.groupby(['Year','Country']).mean()
Funciones de agregación#
count | Number of non-null observations |
sum | Sum of values |
mean | Mean of values |
mad | Mean absolute deviation |
median | Arithmetic median of values |
min | Minimum |
max | Maximum |
mode | Mode |
abs | Absolute Value |
prod | Product of values |
std | Unbiased standard deviation |
var | Unbiased variance |
sem | Unbiased standard error of the mean |
skew | Unbiased skewness (3rd moment) |
kurt | Unbiased kurtosis (4th moment) |
quantile | Sample quantile (value at %) |
cumsum | Cumulative sum |
cumprod | Cumulative product |
cummax | Cumulative maximum |
cummin | Cumulative minimum |
Operaciones#
df_one = pd.DataFrame({'k1':['A','A','B','B','C','C'],
'col1':[100,200,300,300,400,500],
'col2':['NY','CA','WA','WA','AK','NV']})
'''
k1 col1 col2
0 A 100 NY
1 A 200 CA
2 B 300 WA
3 B 300 WA
4 C 400 AK
5 C 500 NV
'''
Valores únicos#
# Devuelve valores únicos de la columna col2
df_one['col2'].unique()
# array(['NY', 'CA', 'WA', 'AK', 'NV'], dtype=object)
# Devuelve número valores únicos de la columna col2
df_one['col2'].nunique()
# 5
# Devuelve tabla con cuenta de cada valor único
df_one['col2'].value_counts()
'''
WA 2
CA 1
NV 1
NY 1
AK 1
Name: col2, dtype: int64
'''
# Eliminar filas duplicadas
df_one.drop_duplicates()
'''
k1 col1 col2
0 A 100 NY
1 A 200 CA
2 B 300 WA
4 C 400 AK
5 C 500 NV
'''
Crear nueva columna con operaciones y funciones#
df_one
'''
k1 col1 col2
0 A 100 NY
1 A 200 CA
2 B 300 WA
3 B 300 WA
4 C 400 AK
5 C 500 NV
'''
# nueva columna 'New col' dependiente de 'col1'
df_one['New Col'] = df_one['col1'] * 10
df_one
'''
k1 col1 col2 New Col
0 A 100 NY 1000
1 A 200 CA 2000
2 B 300 WA 3000
3 B 300 WA 3000
4 C 400 AK 4000
5 C 500 NV 5000
'''
# Aplicar funciones a una columna
def grab_first_letter(state):
# Devuelve primera letra del valor
return state[0]
df_one['col2'].apply(grab_first_letter)
'''
0 N
1 C
2 W
3 W
4 A
5 N
Name: col2, dtype: object
'''
df_one['first letter'] = df_one['col2'].apply(grab_first_letter)
'''
k1 col1 col2 New Col first letter
0 A 100 NY 1000 N
1 A 200 CA 2000 C
2 B 300 WA 3000 W
3 B 300 WA 3000 W
4 C 400 AK 4000 A
5 C 500 NV 5000 N
'''
Mapas#
df_one['k1']
'''
0 A
1 A
2 B
3 B
4 C
5 C
Name: k1, dtype: object
'''
df_one['k1'].map({'A':1,'B':2,'C':3})
'''
0 1
1 1
2 2
3 2
4 3
5 3
Name: k1, dtype: int64
'''
Localizar maximos y mínimos#
# Valor máximo de una columna
df_one['col1'].max()
# 500
# Valor mínimo de una columna
df_one['col1'].min()
# 100
# Índice con valor máximo de una columna
df_one['col1'].idxmax()
# 500
# VÍndice con valor mínimo de una columna
df_one['col1'].idxmin()
# 100
Conseguir nombres de columnas e índices#
# Conseguir nombres de columnas
df_one.columns
# Index(['k1', 'col1', 'col2', 'New Col', ... ], dtype='object')
# Índices
df_one.index
# RangeIndex(start=0, stop=6, step=1)
# Cambiar nombres de columnas
df_one.columns = ['C1','C2','C3', 'C4']
'''
C1 C2 C3 C4
0 A 100 NY 1000
1 A 200 CA 2000
2 B 300 WA 3000
3 B 300 WA 3000
4 C 400 AK 4000
5 C 500 NV 500
'''
Ordenar tabla con valores de una columna#
df_one
'''
C1 C2 C3 C4
0 A 100 NY 1000
1 A 200 CA 2000
2 B 300 WA 3000
3 B 300 WA 3000
4 C 400 AK 4000
5 C 500 NV 500
'''
df_one.sort_values('C3')
'''
C1 C2 C3 C4
4 C 400 AK 4000
1 A 200 CA 2000
5 C 500 NV 5000
0 A 100 NY 1000
2 B 300 WA 3000
3 B 300 WA 3000
'''
Concatenar tablas#
features = pd.DataFrame({'A':[100,200,300,400,500],
'B':[12,13,14,15,16]})
predictions = pd.DataFrame({'pred':[0,1,1,0,1]})
features
'''
A B
0 100 12
1 200 13
2 300 14
3 400 15
4 500 16
'''
predictions
'''
pred
0 0
1 1
2 1
3 0
4 1
'''
# Concatenar = Unir tablas
pd.concat([features,predictions]) # Atención con los ejes
'''
A B pred
0 100.0 12.0 NaN
1 200.0 13.0 NaN
2 300.0 14.0 NaN
3 400.0 15.0 NaN
4 500.0 16.0 NaN
0 NaN NaN 0.0
1 NaN NaN 1.0
2 NaN NaN 1.0
3 NaN NaN 0.0
4 NaN NaN 1.0
'''
pd.concat([features,predictions],axis=1) # Atención con los ejes
'''
A B pred
0 100 12 0
1 200 13 1
2 300 14 1
3 400 15 0
4 500 16 1
'''
Crear variable dummy#
df_one['C1']
'''
0 A
1 A
2 B
3 B
4 C
5 C
Name: C1, dtype: object
'''
pd.get_dummies(df_one['C1'])
'''
A B C
0 1 0 0
1 1 0 0
2 0 1 0
3 0 1 0
4 0 0 1
5 0 0 1
'''