Применяются Pandas: первая строка уточняется дважды - PullRequest
1 голос
/ 14 июля 2020
  • Pandas 1.0.5
  • Python 3.8.0
  • Numpy 1.19.0

Этот код ведет себя странно:

import pandas as pd

def calc(row):
    print(f"Row: {row.to_list()}")
    result = pd.Series({
        "sum1": row.col1 + row.col2,
        "sum2": row.col2 + row.col3,
        "sum3": row.col1 + row.col3,
    })
    return result
    
df = pd.DataFrame({"col1":[1,2,3], 
                   "col2":[4,5,6], 
                   "col3":[7,8,9]})

df[["sum12", "sum23", "sum13"]] = df.apply(lambda row: calc(row), axis=1)
print(df)

Возвращает

Row: [1, 4, 7]
Row: [1, 4, 7]
Row: [2, 5, 8]
Row: [3, 6, 9]

    col1    col2    col3    sum12   sum23   sum13
0    1       4       7       5       11      8
1    2       5       8       7       13     10
2    3       6       9       9       15     12

Первый вопрос:

Почему первая строка уточняется дважды?

Второй вопрос , возможно, связанный с первым:

В моем реальном коде разработка первой строки занимает 0,15 секунды (читается time.process_time()), следующие строки находятся между 0,53 и 0,60. Первая строка обрабатывается дважды, первый раз 0,15 секунды, второй раз 0,55 секунды.

В чем может быть причина, поскольку данные единообразны, только numpy используется в calc(), и нет никаких условных выражений ни фильтры данных задействованы?

1 Ответ

1 голос
/ 14 июля 2020

Это известная проблема для GroupBy.apply (pandas <0,25) и <code>df.apply (pandas <1,1). Причина, по которой первая группа оценивается дважды, заключается в том, что <code>apply хочет знать, может ли он «оптимизировать» вычисления (иногда это возможно, если apply получает numpy или cythonized функцию).

With pandas 0.25, это поведение исправлено для GroupBy.apply. См. здесь . Теперь с pandas 1.1, такое же поведение будет исправлено для df.apply.

Когда версия 1.1 выйдет, вы сможете выполнить обновление, и тогда вы увидите только первый группа оценивается только один раз:

pd.__version__
# '1.1.0.dev0+2004.g8d10bfb6f'

df[["sum12", "sum23", "sum13"]] = df.apply(lambda row: calc(row), axis=1)
print(df)
Row: [1, 4, 7]
Row: [2, 5, 8]
Row: [3, 6, 9]
   col1  col2  col3  sum12  sum23  sum13
0     1     4     7      5     11      8
1     2     5     8      7     13     10
2     3     6     9      9     15     12
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...