Asignación de columna super simple
Un marco de datos de pandas se implementa como un dict ordenado de columnas.
Esto significa que __getitem__
[]
no solo se puede usar para obtener una determinada columna, sino que __setitem__
[] =
se puede usar para asignar una nueva columna.
Por ejemplo, este marco de datos puede tener una columna agregada simplemente usando el descriptor de []
acceso
size name color
0 big rose red
1 small violet blue
2 small tulip red
3 small harebell blue
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
Tenga en cuenta que esto funciona incluso si el índice del marco de datos está desactivado.
df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
[] = es el camino a seguir, ¡pero cuidado!
Sin embargo, si tiene un pd.Series
e intenta asignarlo a un marco de datos donde los índices están apagados, se encontrará con problemas. Ver ejemplo:
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
Esto se debe a que pd.Series
por defecto tiene un índice enumerado de 0 a n. Y el [] =
método de los pandas intenta ser "inteligente"
Lo que realmente está pasando.
Cuando usas el [] =
método, pandas realiza silenciosamente una combinación externa o una combinación externa utilizando el índice del marco de datos de la izquierda y el índice de la serie de la derecha.df['column'] = series
Nota al margen
Esto rápidamente causa disonancia cognitiva, ya que el []=
método está tratando de hacer muchas cosas diferentes dependiendo de la entrada, y el resultado no puede predecirse a menos que solo sepa cómo funcionan los pandas. Por lo tanto, aconsejaría contra las []=
bases de código, pero al explorar datos en un cuaderno, está bien.
Dando la vuelta al problema
Si tiene un pd.Series
y desea asignarlo de arriba a abajo, o si está codificando código productivo y no está seguro del orden del índice, vale la pena salvaguardarlo para este tipo de problema.
Podrías abatir el pd.Series
a a np.ndarray
o a list
, esto hará el truco.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values
o
df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))
Pero esto no es muy explícito.
Algún codificador puede venir y decir "Oye, esto parece redundante, simplemente lo optimizaré".
Manera explícita
Establecer el índice de pd.Series
ser el índice de df
es explícito.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)
O de manera más realista, es probable que pd.Series
ya tenga una disponible.
protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index
3 no
2 no
1 no
0 yes
Ahora se puede asignar
df['protected'] = protected_series
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
Forma alternativa con df.reset_index()
Dado que la disonancia del índice es el problema, si considera que el índice del marco de datos no debe dictar cosas, simplemente puede soltar el índice, esto debería ser más rápido, pero no es muy limpio, ya que su función ahora probablemente hace dos cosas.
df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
Nota sobre df.assign
Si bien df.assign
es más explícito lo que está haciendo, en realidad tiene los mismos problemas que los anteriores[]=
df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
Solo ten cuidado con df.assign
que tu columna no se llame self
. Causará errores. Esto hace df.assign
mal olor , ya que hay este tipo de artefactos en la función.
df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'
Puede decir: "Bueno, self
entonces no lo usaré ". Pero quién sabe cómo cambia esta función en el futuro para respaldar nuevos argumentos. Tal vez el nombre de su columna sea un argumento en una nueva actualización de pandas, causando problemas con la actualización.