He estado muy confundido acerca de cómo se definen los ejes de Python y si se refieren a filas o columnas de un DataFrame. Considere el siguiente código:
>>> df = pd.DataFrame([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]], columns=["col1", "col2", "col3", "col4"])
>>> df
col1 col2 col3 col4
0 1 1 1 1
1 2 2 2 2
2 3 3 3 3
Entonces, si llamamos df.mean(axis=1), obtendremos una media en las filas:
>>> df.mean(axis=1)
0 1
1 2
2 3
Sin embargo, si llamamos df.drop(name, axis=1), en realidad soltamos una columna , no una fila:
>>> df.drop("col4", axis=1)
col1 col2 col3
0 1 1 1
1 2 2 2
2 3 3 3
¿Alguien puede ayudarme a comprender qué se entiende por "eje" en pandas / numpy / scipy?
Una nota al margen, DataFrame.meanpodría definirse mal. Dice en la documentación DataFrame.meanque axis=1se supone que significa una media sobre las columnas, no las filas ...

meany losdrop. Se necesita un pensamiento no lineal para llegar a la conducta real.Respuestas:
Quizás sea más simple recordarlo como 0 = hacia abajo y 1 = a lo ancho .
Esto significa:
axis=0para aplicar un método en cada columna o en las etiquetas de las filas (el índice).axis=1para aplicar un método en cada fila o en las etiquetas de las columnas.Aquí hay una imagen para mostrar las partes de un DataFrame a las que se refiere cada eje:
También es útil recordar que Pandas sigue el uso que hace NumPy de la palabra
axis. El uso se explica en el glosario de términos de NumPy :Entonces, con respecto al método en la pregunta
df.mean(axis=1), parece estar correctamente definido. Toma la media de las entradas horizontalmente en las columnas , es decir, a lo largo de cada fila individual. Por otro lado,df.mean(axis=0)sería una operación que actúe verticalmente hacia abajo a través de filas .Del mismo modo, se
df.drop(name, axis=1)refiere a una acción en las etiquetas de las columnas, ya que atraviesan intuitivamente el eje horizontal. Especificaraxis=0haría que el método actúe en filas.fuente
df.applycomo similar a un método comodf.sum. Por ejemplo,df.sum(axis=0)suma cada columna del DataFrame. Del mismo modo, puede escribirdf.apply(sum, axis=0)para realizar exactamente la misma operación. Si bien la operación se aplica a cada columna en el DataFrame, la función real se ejecuta en el eje 0.MARGIN(similar aaxisen pandas) de "1" corresponde a "filas", lo que significa que la función se aplica a cada fila , mientras que la un valor mayor de "2" se refiere a "columnas", lo que significa que la función se aplica a cada columna .Otra forma de explicar:
// Not realistic but ideal for understanding the axis parameter df = pd.DataFrame([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]], columns=["idx1", "idx2", "idx3", "idx4"], index=["idx1", "idx2", "idx3"] ) ---------------------------------------1 | idx1 idx2 idx3 idx4 | idx1 1 1 1 1 | idx2 2 2 2 2 | idx3 3 3 3 3 0Acerca de
df.drop(el eje significa la posición)A: I wanna remove idx3. B: **Which one**? // typing while waiting response: df.drop("idx3", A: The one which is on axis 1 B: OK then it is >> df.drop("idx3", axis=1) // Result ---------------------------------------1 | idx1 idx2 idx4 | idx1 1 1 1 | idx2 2 2 2 | idx3 3 3 3 0Acerca de
df.apply(eje significa dirección)A: I wanna apply sum. B: Which direction? // typing while waiting response: df.apply(lambda x: x.sum(), A: The one which is on *parallel to axis 0* B: OK then it is >> df.apply(lambda x: x.sum(), axis=0) // Result idx1 6 idx2 6 idx3 6 idx4 6fuente
Ya hay respuestas adecuadas, pero les doy otro ejemplo con> 2 dimensiones.
El parámetro
axissignifica el eje que se va a cambiar .Por ejemplo, considere que hay un marco de datos con dimensión axbxc .
df.mean(axis=1)devuelve un marco de datos con dimensión ax 1 xc .df.drop("col4", axis=1)devuelve un marco de datos con dimensión ax (b-1) xc .Aquí,
axis=1significa el segundo eje que esb, por lo que elbvalor se cambiará en estos ejemplos.fuente
Debería ser más conocido que los alias de cadena 'índice' y 'columnas' pueden usarse en lugar de los enteros 0/1. Los alias son mucho más explícitos y me ayudan a recordar cómo se realizan los cálculos. Otro alias para 'índice' es 'filas' .
Cuando
axis='index'se usa, los cálculos se realizan en las columnas, lo cual es confuso. Pero, lo recuerdo como obtener un resultado que es del mismo tamaño que otra fila.Pongamos algunos datos en la pantalla para ver de qué estoy hablando:
df = pd.DataFrame(np.random.rand(10, 4), columns=list('abcd')) a b c d 0 0.990730 0.567822 0.318174 0.122410 1 0.144962 0.718574 0.580569 0.582278 2 0.477151 0.907692 0.186276 0.342724 3 0.561043 0.122771 0.206819 0.904330 4 0.427413 0.186807 0.870504 0.878632 5 0.795392 0.658958 0.666026 0.262191 6 0.831404 0.011082 0.299811 0.906880 7 0.749729 0.564900 0.181627 0.211961 8 0.528308 0.394107 0.734904 0.961356 9 0.120508 0.656848 0.055749 0.290897Cuando queremos tomar la media de todas las columnas, usamos
axis='index'para obtener lo siguiente:df.mean(axis='index') a 0.562664 b 0.478956 c 0.410046 d 0.546366 dtype: float64El mismo resultado se obtendría mediante:
df.mean() # default is axis=0 df.mean(axis=0) df.mean(axis='rows')Para usar una operación de izquierda a derecha en las filas, use axis = 'columnas'. Lo recuerdo pensando que se puede agregar una columna adicional a mi DataFrame:
df.mean(axis='columns') 0 0.499784 1 0.506596 2 0.478461 3 0.448741 4 0.590839 5 0.595642 6 0.512294 7 0.427054 8 0.654669 9 0.281000 dtype: float64El mismo resultado se obtendría mediante:
df.mean(axis=1)Agregue una nueva fila con eje = 0 / índice / filas
Usemos estos resultados para agregar filas o columnas adicionales para completar la explicación. Entonces, siempre que use axis = 0 / index / rows, es como obtener una nueva fila del DataFrame. Agreguemos una fila:
df.append(df.mean(axis='rows'), ignore_index=True) a b c d 0 0.990730 0.567822 0.318174 0.122410 1 0.144962 0.718574 0.580569 0.582278 2 0.477151 0.907692 0.186276 0.342724 3 0.561043 0.122771 0.206819 0.904330 4 0.427413 0.186807 0.870504 0.878632 5 0.795392 0.658958 0.666026 0.262191 6 0.831404 0.011082 0.299811 0.906880 7 0.749729 0.564900 0.181627 0.211961 8 0.528308 0.394107 0.734904 0.961356 9 0.120508 0.656848 0.055749 0.290897 10 0.562664 0.478956 0.410046 0.546366Agregue una nueva columna con eje = 1 / columnas
De manera similar, cuando el eje = 1 / columnas, creará datos que se pueden convertir fácilmente en su propia columna:
df.assign(e=df.mean(axis='columns')) a b c d e 0 0.990730 0.567822 0.318174 0.122410 0.499784 1 0.144962 0.718574 0.580569 0.582278 0.506596 2 0.477151 0.907692 0.186276 0.342724 0.478461 3 0.561043 0.122771 0.206819 0.904330 0.448741 4 0.427413 0.186807 0.870504 0.878632 0.590839 5 0.795392 0.658958 0.666026 0.262191 0.595642 6 0.831404 0.011082 0.299811 0.906880 0.512294 7 0.749729 0.564900 0.181627 0.211961 0.427054 8 0.528308 0.394107 0.734904 0.961356 0.654669 9 0.120508 0.656848 0.055749 0.290897 0.281000Parece que puede ver todos los alias con las siguientes variables privadas:
df._AXIS_ALIASES {'rows': 0} df._AXIS_NUMBERS {'columns': 1, 'index': 0} df._AXIS_NAMES {0: 'index', 1: 'columns'}fuente
Cuando eje = 'filas' o eje = 0, significa elementos de acceso en la dirección de las filas, de arriba a abajo. Si aplica la suma a lo largo del eje = 0, nos dará los totales de cada columna.
Cuando eje = 'columnas' o eje = 1, significa elementos de acceso en la dirección de las columnas, de izquierda a derecha. Si aplica la suma a lo largo del eje = 1, obtendremos los totales de cada fila.
¡Todavía confuso! Pero lo anterior me lo pone un poco más fácil.
fuente
Encuentro todas las otras respuestas confusas. Así es como lo pienso:
Entonces
df.drop(name, axis=1): suelta una columnadf.mean(axis=1): calcula una columna (el resultado se puede agregar como una nueva columna)fuente