Неоднозначность в Pandas Определение оси "Dataframe/Numpy Array"

Я очень смутился о том, как определяются оси python и относятся ли они к строкам или столбцам DataFrame. Рассмотрим следующий код:

>>> 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

Итак, если мы назовем df.mean(axis=1), мы получим среднее значение по строкам:

>>> df.mean(axis=1)
0    1
1    2
2    3

Однако, если мы вызываем df.drop(name, axis=1), мы фактически удаляем столбец, а не строку:

>>> df.drop("col4", axis=1)
   col1  col2  col3
0     1     1     1
1     2     2     2
2     3     3     3

Может кто-нибудь помочь мне понять, что подразумевается под "осью" в pandas/numpy/scipy?

Боковое примечание, DataFrame.mean просто может быть определено неправильно. В документации для DataFrame.mean говорится, что axis=1 означает среднее значение по столбцам, а не строки...

Ответ 1

Возможно, проще всего запомнить его как 0 = вниз и 1 = поперек.

Это означает:

  • Используйте axis=0 для применения метода к каждому столбцу или к ярлыкам строк (индекс).
  • Используйте axis=1 для применения метода к каждой строке или к меткам столбца.

Здесь показано изображение частей DataFrame, на которые ссылается каждая ось:

DL0iQ.jpg

Также полезно помнить, что Pandas следует за использованием NumPy слова axis. Использование объясняется в NumPy глоссарии терминов:

Оси определены для массивов с более чем одним измерением. 2-мерный массив имеет две соответствующие оси: первая выполняется вертикально вниз по строкам (ось 0), а вторая выполняется горизонтально по столбцам (ось 1). [мой акцент]

Итак, относительно метода в вопросе df.mean(axis=1), кажется, правильно определено. Он принимает среднее значение в горизонтальной позиции по столбцам, то есть по каждой отдельной строке. С другой стороны, df.mean(axis=0) - это операция, действующая вертикально вниз по строкам.

Аналогично, df.drop(name, axis=1) относится к действию на ярлыках столбцов, потому что они интуитивно проходят горизонтальную ось. Задание axis=0 приведет к тому, что метод будет действовать на строки.

Ответ 2

Другой способ объяснить:

// 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

О df.drop (ось означает позицию)

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

О df.apply (направление оси означает)

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

Ответ 3

Уже есть правильные ответы, но я даю вам еще один пример s > 2 измерениями.

Параметр axis означает изменяемую ось.
Например, учтите, что существует размерная диаграмма с размером a x b x c.

  • df.mean(axis=1) возвращает dataframe с dimenstion a x 1 x c.
  • df.drop("col4", axis=1) возвращает dataframe с размером a x (b-1) x c.

Ответ 4

Должно быть более широко известно, что вместо целых чисел 0/1 можно использовать строковые псевдонимы 'index' и 'столбцы. Алиасы гораздо более ясны и помогают мне помнить, как происходит расчет. Другим псевдонимом для индекса является 'rows'.

Когда используется axis='index', вычисления выполняются по столбцам, что путает. Но я помню, что это результат, равный размеру другой строки.

Позвольте получить некоторые данные на экране, чтобы увидеть, о чем я говорю:

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

Если мы хотим принять среднее значение для всех столбцов, мы используем axis='index', чтобы получить следующее:

df.mean(axis='index')
a    0.562664
b    0.478956
c    0.410046
d    0.546366
dtype: float64

Тот же результат будет получен:

df.mean() # default is axis=0
df.mean(axis=0)
df.mean(axis='rows')

Чтобы использовать операцию слева направо в строках, используйте axis = 'columns'. Я помню это, думая, что в мой 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

Тот же результат будет получен:

df.mean(axis=1)

Добавить новую строку с осью = 0/index/rows

Используйте эти результаты, чтобы добавить дополнительные строки или столбцы, чтобы завершить объяснение. Таким образом, всякий раз, когда используется ось = 0/index/rows, это похоже на получение новой строки DataFrame. Добавьте строку:

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

Добавить новый столбец с осью = 1/столбцы

Аналогично, когда axis = 1/columns, он создаст данные, которые можно легко сделать в свой собственный столбец:

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

Похоже, вы можете увидеть все псевдонимы со следующими частными переменными:

df._AXIS_ALIASES
{'rows': 0}

df._AXIS_NUMBERS
{'columns': 1, 'index': 0}

df._AXIS_NAMES
{0: 'index', 1: 'columns'}

Ответ 5

Когда axis = 'lines' или axis = 0, это означает доступ к элементам в направлении строк, вверх-вниз. Если применить сумму по оси = 0, это даст нам итоги каждого столбца.

Когда axis = 'columns' или axis = 1, это означает доступ к элементам в направлении столбцов слева направо. Если применить сумму по оси = 1, мы получим итоги по каждой строке.

Все еще сбивает с толку! Но вышеизложенное делает это немного легче для меня.