Estoy muy confundido con los diferentes métodos de indexación que se usan iloc
en los pandas.
Digamos que estoy tratando de convertir un Dataframe 1-d en un Dataframe 2-d. Primero tengo el siguiente marco de datos 1-d
a_array = [1,2,3,4,5,6,7,8]
a_df = pd.DataFrame(a_array).T
Y voy a convertir eso en un Dataframe 2-d con el tamaño de 2x4
. Comienzo preseleccionando el Dataframe 2-d de la siguiente manera:
b_df = pd.DataFrame(columns=range(4),index=range(2))
Luego uso for-loop para ayudarme a convertir a_df
(1-d) a b_df
(2-d) con el siguiente código
for i in range(2):
b_df.iloc[i,:] = a_df.iloc[0,i*4:(i+1)*4]
Solo me da los siguientes resultados
0 1 2 3
0 1 2 3 4
1 NaN NaN NaN NaN
Pero cuando me cambié b_df.iloc[i,:]
a b_df.iloc[i][:]
. El resultado es correcto como el siguiente, que es lo que quiero
0 1 2 3
0 1 2 3 4
1 5 6 7 8
¿Alguien podría explicarme cuál es la diferencia entre .iloc[i,:]
y .iloc[i][:]
, y por qué .iloc[i][:]
funcionó en mi ejemplo anterior pero no.iloc[i,:]
b_df.iloc[1] = a_df.iloc[0, 4:8]
asigna una serie con índice[4, 5, 6, 7]
a una serie con índice[0, 1, 2, 3]
. No hay superposición, por lo queNaN
se asignan a todos los elementos. Hasta este punto tiene sentido para mí. Pero, como usted, no tengo claro por qué seb_df.iloc[1][:] = ...
comporta de manera diferente: inspeccionar los objetosb_df.iloc[1]
yb_df.iloc[1][:]
no revela diferencias entre los índices. Mi mejor conjetura sería que la asignación directa a una copia ([:]
) es tratada como un caso especial por Pandas, lo que hace que ignore el índice del cesionario y cree esta discrepancia.Respuestas:
Hay una muy, muy grande diferencia entre
series.iloc[:]
yseries[:]
, al asignar de nuevo.(i)loc
siempre verifica que lo que sea que esté asignando coincida con el índice del cesionario. Mientras tanto, la[:]
sintaxis se asigna a la matriz subyacente NumPy, sin pasar por la alineación del índice.Ahora que comprende la diferencia, veamos qué sucede en su código. Simplemente imprima el RHS de sus bucles para ver lo que está asignando:
Al asignar a
b_df.iloc[i, :]
en la segunda iteración, los índices son diferentes, por lo que no se asigna nada y solo se ven los NaN. Sin embargo, cambiarb_df.iloc[i, :]
ab_df.iloc[i][:]
significará que asigna a la matriz NumPy subyacente, por lo que se omite la alineación de indexación. Esta operación se expresa mejor comoTambién vale la pena mencionar que esta es una forma de asignación encadenada, que no es algo bueno , y también hace que su código sea más difícil de leer y comprender.
fuente
[:]
sintaxis se asigna a la matriz subyacente NumPy"?La diferencia es que en el primer caso el intérprete de Python ejecutó el código como:
donde el valor sería el lado derecho de la ecuación. Mientras que en el segundo caso, el intérprete de Python ejecutó el código como:
donde nuevamente el valor sería el lado derecho de la ecuación.
En cada uno de esos dos casos, se llamaría un método diferente dentro del setitem debido a la diferencia en las teclas (i, slice (None)) y slice (None) Por lo tanto, tenemos un comportamiento diferente.
fuente
b_df.iloc[i]
yb_df.iloc[i][:]
tienen los mismos índices sin embargo. ¿Por qué puede asignar una serie con índice no coincidente a una pero no a la otra?La diferencia entre
.iloc[i,:]
y.iloc[i][:]
En el caso de
.iloc[i,:]
que esté accediendo directamente a una posición específica deDataFrame
, seleccionando todas las:
columnas ( ) de lai
fila th. Que yo sepa, es equivalente a dejar la segunda dimensión sin especificar (.iloc[i]
).En el caso de
.iloc[i][:]
que esté realizando 2 operaciones encadenadas. Entonces, el resultado de.iloc[i]
será afectado por[:]
. El uso de esto para establecer valores es desaconsejado por Pandas mismo aquí con una advertencia, por lo que no debe usarlo:Como @Scott mencionó en los comentarios de OP, la alineación de datos es intrínseca , por lo que los índices en el lado derecho
=
no se incluirán si no están presentes en el lado izquierdo. Por eso hayNaN
valores en la segunda fila.Entonces, para dejar las cosas claras, puede hacer lo siguiente:
O puede convertir a en
list
lugar de usarreset_index
:fuente