Как получить результат, определив функцию деления с помощью панд?

def set_div(a,b):
    if a==0:
        if b==0:
            return 0
        else:
            return 10**6
    else:
        return b/a

ДФ:

    a       b
0   0.0     0.0
1   30000.0 0.0
2   0.0     0.0
3   32700.0 10000.0
4   51700.0 0.0

dтипы столбцов a и b float64.

df['c'] = df[['a','b']].apply(lambda x:set_div(x[0],x[1])) 

но он возвращается KeyError: (0, 'occurred at index a').

Я не понимаю ошибку, пожалуйста, объясните и как получить мой результат.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
196
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если вы хотите использовать пользовательскую функцию, работающую для каждой строки, нужно DataFrame.apply с axis=1:

df['c'] = df.apply(lambda x :set_div(x['a'],x['b']), axis=1) 

Другое решение с numpy.select векторизовано, поэтому производительность выше в больших DataFrame:

m1 = df['a'] == 0
m2 = df['b'] == 0
df['c'] = np.select([m1 & ~m2, m1 & m2], [10**6, 0], df['b'] / df['a'])
print (df)
         a        b        c
0      0.0      0.0  0.00000
1  30000.0      0.0  0.00000
2      0.0      0.0  0.00000
3  32700.0  10000.0  0.30581
4  51700.0      0.0  0.00000

Представление:

#[50000 rows x 2 columns]
df = pd.concat([df] * 10000, ignore_index=True)

In [113]: %timeit df['c'] = np.select([m1 & ~m2, m1 & m2], [10**6, 0], df['b'] / df['a'])
1.85 ms ± 32.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [114]: %timeit df['c1'] = df.apply(lambda x :set_div(x['a'],x['b']), axis=1)
1.01 s ± 17.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Вы можете получить желаемый результат напрямую, используя numpy where следующим образом:

df['c'] = numpy.where(df.a == 0, numpy.where(df.b == 0, 0, 10**6), df.b/df.a)

print(df)

Результат:

       a      b        c
0      0      0  0.00000
1  30000      0  0.00000
2      0      0  0.00000
3  32700  10000  0.30581
4  51700      0  0.00000

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

Другие вопросы по теме