#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).
У меня есть два вопроса:
- Почему str.contains(‘.’) не работает в этом контексте? Кажется, что это самый простой способ, поскольку он в 100% случаев дает мне то, что мне нужно в моих данных, но возвращает True, даже если в значении явно отсутствует символ ‘.’.
- Как я могу правильно идентифицировать все значения [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. Извините меня, пока я кричу в подушку (но спасибо).