Сравнение поплавков в колонне панд

У меня есть следующий фрейм данных:

       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()
Другие вопросы по тегам