Estou muito confuso sobre como os eixos Python são definidos e se eles se referem às linhas ou colunas de um DataFrame. Considere o código abaixo:
>>> 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
Portanto, se chamarmos df.mean(axis=1)
, obteremos uma média nas linhas:
>>> df.mean(axis=1)
0 1
1 2
2 3
No entanto, se chamarmos df.drop(name, axis=1)
, na verdade eliminamos uma coluna , não uma linha:
>>> df.drop("col4", axis=1)
col1 col2 col3
0 1 1 1
1 2 2 2
2 3 3 3
Alguém pode me ajudar a entender o que significa "eixo" em pandas / numpy / scipy?
Uma nota lateral, DataFrame.mean
só pode ser definida incorretamente. Diz na documentação DataFrame.mean
que axis=1
isso significa uma média sobre as colunas, não as linhas ...
mean
e odrop
. É necessário pensamento não linear para chegar ao comportamento real.Respostas:
Talvez seja mais simples lembrá-lo como 0 = para baixo e 1 = transversalmente .
Isso significa:
axis=0
para aplicar um método a cada coluna ou aos rótulos de linha (o índice).axis=1
para aplicar um método em cada linha ou nos rótulos das colunas.Aqui está uma imagem para mostrar as partes de um DataFrame a que cada eixo se refere:
Também é útil lembrar que o Pandas segue o uso da palavra por NumPy
axis
. O uso é explicado no glossário de termos do NumPy :Então, no que diz respeito ao método em questão
df.mean(axis=1)
,, parece estar corretamente definido. Ele pega a média das entradas horizontalmente nas colunas , ou seja, ao longo de cada linha individual. Por outro lado,df.mean(axis=0)
seria uma operação atuando verticalmente para baixo nas linhas .Da mesma forma,
df.drop(name, axis=1)
refere-se a uma ação nos rótulos das colunas, porque eles passam intuitivamente pelo eixo horizontal. Especificaraxis=0
faria o método agir nas linhas.fonte
df.apply
um método semelhante adf.sum
. Por exemplo,df.sum(axis=0)
soma cada coluna do DataFrame. Da mesma forma, você pode escreverdf.apply(sum, axis=0)
para fazer exatamente a mesma operação. Embora a operação seja de fato aplicada a cada coluna no DataFrame, a função real é executada no eixo 0.MARGIN
(semelhante aaxis
nos pandas) de "1" corresponde a "linhas", o que significa que a função é aplicada a cada linha , enquanto o o valor maior de "2" refere-se a "colunas", o que significa que a função é aplicada a cada coluna .Outra maneira 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 0
Sobre
df.drop
(eixo significa a posição)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 0
Sobre
df.apply
(eixo significa direção)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 6
fonte
Já existem respostas adequadas, mas dou outro exemplo com> 2 dimensões.
O parâmetro
axis
significa eixo a ser alterado .Por exemplo, considere que existe um dataframe com dimensão axbxc .
df.mean(axis=1)
retorna um dataframe com dimensão ax 1 xc .df.drop("col4", axis=1)
retorna um dataframe com dimensão ax (b-1) xc .Aqui,
axis=1
significa o segundo eixo, que éb
, portanto, ob
valor será alterado nestes exemplos.fonte
Deve ser mais amplamente conhecido que os aliases de string 'índice' e 'colunas' podem ser usados no lugar dos inteiros 0/1. Os apelidos são muito mais explícitos e me ajudam a lembrar como os cálculos ocorrem. Outro alias para 'índice' é 'linhas' .
Quando
axis='index'
é usado, os cálculos acontecem nas colunas, o que é confuso. Mas, lembro-me de obter um resultado que é do mesmo tamanho que outra linha.Vamos colocar alguns dados na tela para ver do que estou falando:
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.290897
Quando queremos obter a média de todas as colunas, usamos
axis='index'
para obter o seguinte:df.mean(axis='index') a 0.562664 b 0.478956 c 0.410046 d 0.546366 dtype: float64
O mesmo resultado seria obtido por:
df.mean() # default is axis=0 df.mean(axis=0) df.mean(axis='rows')
Para usar uma operação da esquerda para a direita nas linhas, use axis = 'colunas'. Lembro-me disso pensando que uma coluna adicional pode ser adicionada ao meu 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: float64
O mesmo resultado seria obtido por:
df.mean(axis=1)
Adicionar uma nova linha com eixo = 0 / índice / linhas
Vamos usar esses resultados para adicionar linhas ou colunas adicionais para completar a explicação. Portanto, sempre que usar axis = 0 / index / rows, é como obter uma nova linha do DataFrame. Vamos adicionar uma linha:
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.546366
Adicione uma nova coluna com eixo = 1 / colunas
Da mesma forma, quando eixo = 1 / colunas, ele criará dados que podem ser facilmente transformados em sua própria coluna:
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.281000
Parece que você pode ver todos os aliases com as seguintes variáveis privadas:
df._AXIS_ALIASES {'rows': 0} df._AXIS_NUMBERS {'columns': 1, 'index': 0} df._AXIS_NAMES {0: 'index', 1: 'columns'}
fonte
Quando eixo = 'linhas' ou eixo = 0, significa acessar os elementos na direção das linhas, de cima para baixo. Se aplicar soma ao longo do eixo = 0, obteremos os totais de cada coluna.
Quando eixo = 'colunas' ou eixo = 1, significa acessar elementos na direção das colunas, da esquerda para a direita. Se aplicar soma ao longo do eixo = 1, obteremos os totais de cada linha.
Ainda confuso! Mas o exposto acima torna tudo um pouco mais fácil para mim.
fonte
Acho todas as outras respostas confusas. Aqui está o que penso sobre isso:
então
df.drop(name, axis=1)
: solta uma colunadf.mean(axis=1)
: calcula uma coluna (o resultado pode ser adicionado como uma nova coluna)fonte