Usando iloc para establecer valores [cerrado]


13

Esta línea devuelve las primeras 4 filas en el marco combinedde datos parafeature_a

combined.iloc[0:4]["feature_a"]

Como se esperaba, esta línea siguiente devuelve las filas 2da, 4ta y 16ta en el marco de datos para la columna feature_a:

combined.iloc[[1,3,15]]["feature_a"]

Esta línea establece las primeras 4 filas en el marco de datos para feature_aa 77.

combined.iloc[0:4]["feature_a"] = 77

Esta línea hace algo. Están ocurriendo algún tipo de cálculos, ya que lleva más tiempo cuando se aplica a una lista más larga.

combined.iloc[[1,3,15]]["feature_a"] = 88

Las filas 2da, 4ta y 16ta no se configuran 88cuando se verifica con esto:

combined.iloc[[1,3,15]]["feature_a"]

¿Cómo puedo establecer una lista arbitraria de filas de una columna de un marco de datos a un valor sin tomar un desvío de codificación masivo?

Este escenario parece que debería ser bastante sencillo y común.


Esta es una pregunta sobre programación solamente (sin estadísticas) y por lo tanto pertenece a Stack Overflow
Jake Westfall

Sin un ejemplo reproducible mínimo, este tipo de pregunta también estaría fuera de tema en stackoverflow
Glen_b -Reinstate Monica

Respuestas:


24

Si invierte los selectores y selecciona primero por columna, funcionará bien:

Código:

df.feature_a.iloc[[1, 3, 15]] = 88

¿Por qué?

Cuando hizo la primera (forma no funcional), está seleccionando una sección no contigua del marco de datos. Deberías haber recibido la advertencia:

Se está intentando establecer un valor en una copia de un segmento de un DataFrame. Intente usar .loc [row_indexer, col_indexer] = value en su lugar

Consulte las advertencias en la documentación: http://pandas.pydata.org/pandas- > docs / stable / indexing.html # indexing-view-versus-copy

Esto se debe a que están teniendo lugar dos operaciones independientes.

  1. combined.iloc[[1,3,15]]crea un nuevo marco de datos de solo tres filas, y el marco se copia necesariamente. luego...
  2. seleccione una columna a través de ["feature_a"] pero se selecciona contra la copia.

Entonces la tarea va a la copia. Hay varias formas de arreglar esto, pero en este caso, es más fácil (y más barato) seleccionar primero la columna, luego seleccionar partes de las columnas para asignarlas.

Código de prueba:

df = pd.DataFrame(np.zeros((20, 3)), columns=['feature_a', 'b', 'c'])
df.feature_a.iloc[[1, 3, 15]] = 88
print(df)

Resultados:

    feature_a    b    c
0         0.0  0.0  0.0
1        88.0  0.0  0.0
2         0.0  0.0  0.0
3        88.0  0.0  0.0
4         0.0  0.0  0.0
5         0.0  0.0  0.0
6         0.0  0.0  0.0
7         0.0  0.0  0.0
8         0.0  0.0  0.0
9         0.0  0.0  0.0
10        0.0  0.0  0.0
11        0.0  0.0  0.0
12        0.0  0.0  0.0
13        0.0  0.0  0.0
14        0.0  0.0  0.0
15       88.0  0.0  0.0
16        0.0  0.0  0.0
17        0.0  0.0  0.0
18        0.0  0.0  0.0
19        0.0  0.0  0.0

1
Esto puede funcionar, pero ¿por qué?
Matthew Drury
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.