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')
.
Я не понимаю ошибку, пожалуйста, объясните и как получить мой результат.
Если вы хотите использовать пользовательскую функцию, работающую для каждой строки, нужно 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
, чтобы он работал по строкам, а не по столбцам.