Сравнение поплавков в колонне панд
У меня есть следующий фрейм данных:
actual_credit min_required_credit
0 0.3 0.4
1 0.5 0.2
2 0.4 0.4
3 0.2 0.3
Мне нужно добавить столбец, указывающий, где actual_credit >= min_required_credit. Результат будет:
actual_credit min_required_credit result
0 0.3 0.4 False
1 0.5 0.2 True
2 0.4 0.4 True
3 0.1 0.3 False
Я делаю следующее:
df['result'] = abs(df['actual_credit']) >= abs(df['min_required_credit'])
Однако 3-й ряд (0,4 и 0,4) постоянно приводит к ложному. После исследования этой проблемы в различных местах, в том числе: Каков наилучший способ сравнения чисел с плавающей точкой на почти равенство в Python? Я до сих пор не могу заставить это работать. Всякий раз, когда два столбца имеют одинаковое значение, результатом является False, что является неверным.
Я использую Python 3.3
4 ответа
Из-за неточного сравнения поплавков вы можете or
ваше сравнение с np.isclose
, isclose
принимает параметр относительной и абсолютной толерантности, поэтому должно работать следующее:
df['result'] = df['actual_credit'].ge(df['min_required_credit']) | np.isclose(df['actual_credit'], df['min_required_credit'])
Ответ @EdChum отлично работает, но использование функции pandas.DataFrame.round - еще один чистый вариант, который хорошо работает без использования
numpy
.
df = pd.DataFrame( # adding a small difference at the thousandths place to reproduce the issue
data=[[0.3, 0.4], [0.5, 0.2], [0.400, 0.401], [0.2, 0.3]],
columns=['actual_credit', 'min_required_credit'])
df['result'] = df['actual_credit'].round(1) >= df['min_required_credit'].round(1)
print(df)
actual_credit min_required_credit result
0 0.3 0.400 False
1 0.5 0.200 True
2 0.4 0.401 True
3 0.2 0.300 False
Вы можете подумать об использовании
round()
для более постоянного редактирования вашего фрейма данных, в зависимости от того, желаете ли вы такой точности или нет. В этом примере кажется, что OP предполагает, что это, вероятно, просто шум и просто вызывает путаницу.
df = pd.DataFrame( # adding a small difference at the thousandths place to reproduce the issue
data=[[0.3, 0.4], [0.5, 0.2], [0.400, 0.401], [0.2, 0.3]],
columns=['actual_credit', 'min_required_credit'])
df = df.round(1)
df['result'] = df['actual_credit'] >= df['min_required_credit']
print(df)
actual_credit min_required_credit result
0 0.3 0.4 False
1 0.5 0.2 True
2 0.4 0.4 True
3 0.2 0.3 False
В основном numpy
Функции сравнения хорошо работают сpd.Series
и позволяют проводить поэлементные сравнения:
isclose
, allclose
, greater
, greater_equal
, less
, less_equal
и т.п.
В твоем случае greater_equal
сделал бы:
df['result'] = np.greater_equal(df['actual_credit'], df['min_required_credit'])
или, как предлагается, используя pandas.ge
(альтернативно le
, gt
так далее.):
df['result'] = df['actual_credit'].ge(df['min_required_credit'])
Риск с or
общаясь с ge
(как упоминалось выше), например, сравнение 3.999999999999
а также 4.0
может вернуться True
что не обязательно может быть тем, что вы хотите.
Использование pandas.DataFrame.abs()
вместо встроенного abs()
:
df['result'] = df['actual_credit'].abs() >= df['min_required_credit'].abs()