Как правильно идентифицировать значения с плавающей запятой [0, 1], содержащие точку, в DataFrame object dtype?

#python #string #pandas #floating-point #contains

#питон #строка #панды #с плавающей запятой #содержит #python #pandas #значение с плавающей запятой

Вопрос:

У меня есть фрейм данных, подобный so, где моими значениями являются object dtype:

 df = pd.DataFrame(data=['A', '290', '0.1744175757', '1', '1.0000000000'], columns=['Value'])

df
Out[65]: 
          Value
0             A
1           290
2  0.1744175757
3             1
4  1.0000000000

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 1 columns):
Value    5 non-null object
dtypes: object(1)
memory usage: 120.0  bytes
  

Что я хочу сделать, это выбрать только проценты, в данном случае значения 0.1744175757 и 1.0000000000, которые просто так случаются в моих данных, будут иметь точку / dot в них. Это ключевой момент — мне нужно уметь различать целое значение 1 и процент 1.0000000000, а также 0 и 0.0000000000.

Я пытался искать наличие символа точки, но это не работает, оно возвращает true для каждого значения, и мне непонятно, почему.

 df[df['Value'].str.contains('.')]
Out[67]: 
          Value
0             A
1           290
2  0.1744175757
3             1
4  1.0000000000
  

Я также пробовал isdecimal(), но это не совсем то, что я хочу:

 df[df['Value'].str.isdecimal()]
Out[68]: 
  Value
1   290
3     1
  

Самая близкая, которую я придумал, функция:

 def isPercent(x):

    if pd.isnull(x):
        return False

    try:
        x = float(x)
        return x % 1 != 0
    except:
        return False

df[df['Value'].apply(isPercent)]
Out[74]: 
          Value
2  0.1744175757
  

но это не позволяет правильно идентифицировать сценарии 1.0000000000 (и 0.0000000000).

У меня есть два вопроса:

  1. Почему str.contains(‘.’) не работает в этом контексте? Кажется, что это самый простой способ, поскольку он в 100% случаев дает мне то, что мне нужно в моих данных, но возвращает True, даже если в значении явно отсутствует символ ‘.’.
  2. Как я могу правильно идентифицировать все значения [0, 1], которые имеют символ точки в значении?

Ответ №1:

str.contains выполняет поиск на основе регулярных выражений по умолчанию, и ‘.’ будет соответствовать любому символу с помощью механизма регулярных выражений. Чтобы отключить это, используйте regex=False :

 df[df['Value'].str.contains('.', regex=False)]

          Value
2  0.1744175757
4  1.0000000000
  

Вы также можете избежать этого, чтобы обработать его буквально:

 df[df['Value'].str.contains(r'.')]

          Value
2  0.1744175757
4  1.0000000000
  

Если вы действительно хотите использовать только числа с плавающей запятой, попробуйте использовать регулярное выражение, которое немного более надежное.

 df[df['Value'].str.contains(r'd .d ')].astype(float)

      Value
2  0.174418
4  1.000000
  

Комментарии:

1. Извините меня, пока я кричу в подушку (но спасибо).