Already some great answers to this question, however here is a nice snippet that I use regularly to drop rows if they have non-numeric values on some columns:
# Eliminate invalid data from dataframe (see Example below for more context)
num_df = (df.drop(data_columns, axis=1)
.join(df[data_columns].apply(pd.to_numeric, errors='coerce')))
num_df = num_df[num_df[data_columns].notnull().all(axis=1)]
The way this works is we first drop
all the data_columns
from the df
, and then use a join
to put them back in after passing them through pd.to_numeric
(with option 'coerce'
, such that all non-numeric entries are converted to NaN
). The result is saved to num_df
.
On the second line we use a filter that keeps only rows where all values are not null.
Note that pd.to_numeric
is coercing to NaN
everything that cannot be converted to a numeric value, so strings that represent numeric values will not be removed. For example '1.25'
will be recognized as the numeric value 1.25
.
Disclaimer: pd.to_numeric
was introduced in pandas version 0.17.0
Example:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({"item": ["a", "b", "c", "d", "e"],
...: "a": [1,2,3,"bad",5],
...: "b":[0.1,0.2,0.3,0.4,0.5]})
In [3]: df
Out[3]:
a b item
0 1 0.1 a
1 2 0.2 b
2 3 0.3 c
3 bad 0.4 d
4 5 0.5 e
In [4]: data_columns = ['a', 'b']
In [5]: num_df = (df
...: .drop(data_columns, axis=1)
...: .join(df[data_columns].apply(pd.to_numeric, errors='coerce')))
In [6]: num_df
Out[6]:
item a b
0 a 1 0.1
1 b 2 0.2
2 c 3 0.3
3 d NaN 0.4
4 e 5 0.5
In [7]: num_df[num_df[data_columns].notnull().all(axis=1)]
Out[7]:
item a b
0 a 1 0.1
1 b 2 0.2
2 c 3 0.3
4 e 5 0.5
При импортировании данных из других источников вы, возможно, уже успели обнаружить, что Excel иногда некорректно импортирует значения. В частности, он может принять ваши числа за текст. И тогда, например, при суммировании диапазона значений формула СУММ возвращает 0 — хотя диапазон, по всей видимости, содержит числовые значения.
Часто Excel сообщает вам об этих «нечислах», отображая смарт-тег, который позволяет преобразовать текст в числа. Если смарт-тег не отображается, вы можете использовать следующий метод, чтобы указать Excel изменить эти «нечисловые» числа на их фактические значения. Выполните следующие действия.
- Активизируйте любую пустую ячейку на листе.
- Нажмите Ctrl+C, чтобы скопировать пустую ячейку.
- Выберите диапазон, содержащий проблематичные значения.
- Выберите Главная ► Буфер обмена ► Вставить ► Специальная вставка для открытия диалогового окна Специальная вставка.
- В окне Специальная вставка установите переключатель Операция в положение сложить.
- Нажмите кнопку ОК.
Excel ничего не добавит к значениям, но в процессе укажет этим ячейкам иметь фактические значения.
По теме
Новые публикации
Вопрос знатокам:
через формат ячеек установила формат — числовой
что уже делать не знаю
регрессия не строится
С уважением, Настя Черкасова
Лучшие ответы
Влад:
включить метки во входной интервал
Видео-ответ
Это видео поможет разобраться
Ответы знатоков
Алекс Куха:
— разделитель целой и др. часть м. б. неправильный
— вместо нуля стоит «О»
В общем, если есть такое сообщение, надо искать, иначе не отвяжется
Ксения Новицкая:
та же проблема, как быть?
Белая роза…..:
Алекс Куха что значит разделить целой, я используя программу впервый раз, не понимаю вашего ответа, возникает такая же ошибка, уже весь интернет обыскала ища решение этой проблемы… но ничего нет
Оксана Володина:
У меня в одной из ячеек пробел после запятой стоял, проверьте все ячейки
Полосатый жираф Алик:
=ЕЧИСЛО (аргумент) возвращает ИСТИНА, если в аргументе число. Или ЛОЖЬ — в противном случае.
Вопрос:
У меня есть большой фреймворк данных в pandas, который, кроме столбца, используемого как индекс, должен иметь только числовые значения:
df = pd.DataFrame({'a': [1, 2, 3, 'bad', 5],
'b': [0.1, 0.2, 0.3, 0.4, 0.5],
'item': ['a', 'b', 'c', 'd', 'e']})
df = df.set_index('item')
Как я могу найти строку фрейма данных df
, в которой есть нечисловое значение?
В этом примере это четвертая строка в фрейме данных, которая имеет строку 'bad'
в столбце a
. Как эта строка может быть найдена программно?
Лучший ответ:
Вы можете использовать np.isreal
, чтобы проверить тип каждого элемента (applymap применяет функцию к каждому элементу в DataFrame):
In [11]: df.applymap(np.isreal)
Out[11]:
a b
item
a True True
b True True
c True True
d False True
e True True
Если все в строке имеют значение Истина, все они являются числовыми:
In [12]: df.applymap(np.isreal).all(1)
Out[12]:
item
a True
b True
c True
d False
e True
dtype: bool
Итак, чтобы получить subDataFrame из rouges, (Примечание: отрицание, ~, из вышеперечисленного находит те, у которых есть хотя бы один изгоев нечисловой):
In [13]: df[~df.applymap(np.isreal).all(1)]
Out[13]:
a b
item
d bad 0.4
Вы также можете найти местоположение первого правонарушителя, которого вы могли бы использовать argmin:
In [14]: np.argmin(df.applymap(np.isreal).all(1))
Out[14]: 'd'
Как указывает @CTZhu, он может быть немного быстрее проверить, является ли это экземпляром либо int, либо float (есть некоторые дополнительные накладные расходы с np.isreal):
df.applymap(lambda x: isinstance(x, (int, float)))
Ответ №1
Уже некоторые замечательные ответы на этот вопрос, однако вот хороший фрагмент, который я использую регулярно, чтобы отбрасывать строки, если у них есть нечисловые значения в некоторых столбцах:
# Eliminate invalid data from dataframe (see Example below for more context)
numdf = (df.drop(data_columns, axis=1)
.join(df[data_columns].apply(pd.to_numeric, errors='coerce')))
numdf = numdf[num_df[data_columns].notnull().all(axis=1)]
Как это работает, мы сначала drop
все data_columns
из df
, а затем используйте join
, чтобы вернуть их после прохождения через pd.to_numeric
(с опцией 'coerce'
, так что все нечисловые записи преобразуются в NaN
). Результат сохраняется до numdf
.
Во второй строке мы используем фильтр, который хранит только строки, где все значения не равны нулю.
Обратите внимание, что pd.to_numeric
принуждает NaN
все, что невозможно преобразовать в числовое значение, поэтому строки, которые представляют числовые значения, не будут удалены. Например, '1.25'
будет распознаваться как числовое значение 1.25
.
Отказ от ответственности: pd.to_numeric
был представлен в версии pandas 0.17.0
Пример:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({"item": ["a", "b", "c", "d", "e"],
...: "a": [1,2,3,"bad",5],
...: "b":[0.1,0.2,0.3,0.4,0.5]})
In [3]: df
Out[3]:
a b item
0 1 0.1 a
1 2 0.2 b
2 3 0.3 c
3 bad 0.4 d
4 5 0.5 e
In [4]: data_columns = ['a', 'b']
In [5]: num_df = (df
...: .drop(data_columns, axis=1)
...: .join(df[data_columns].apply(pd.to_numeric, errors='coerce')))
In [6]: num_df
Out[6]:
item a b
0 a 1 0.1
1 b 2 0.2
2 c 3 0.3
3 d NaN 0.4
4 e 5 0.5
In [7]: num_df[num_df[data_columns].notnull().all(axis=1)]
Out[7]:
item a b
0 a 1 0.1
1 b 2 0.2
2 c 3 0.3
4 e 5 0.5
Ответ №2
Извините за путаницу, это должен быть правильный подход. Вы хотите только захватить только 'bad'
, а не такие вещи, как 'good'
; Или просто любые не численные значения?
In[15]:
np.where(np.any(np.isnan(df.convert_objects(convert_numeric=True)), axis=1))
Out[15]:
(array([3]),)
Ответ №3
# Original code
df = pd.DataFrame({'a': [1, 2, 3, 'bad', 5],
'b': [0.1, 0.2, 0.3, 0.4, 0.5],
'item': ['a', 'b', 'c', 'd', 'e']})
df = df.set_index('item')
Преобразовать в числовое значение с помощью ‘coerce’, который заполняет неверные значения с помощью ‘nan’
a = pd.to_numeric(df.a, errors='coerce')
Используйте isna для возврата логического индекса:
idx = a.isna()
Примените этот индекс к фрейму данных:
df[idx]
выход
Возвращает строку с неверными данными в ней:
a b
item
d bad 0.4
Ответ №4
Если вы работаете со столбцом со строковыми значениями, вы можете использовать
ОЧЕНЬ ПОЛЕЗНАЯ функция series.str.isnumeric() как:
a = pd.Series(['hi','hola','2.31','288','312','1312', '0,21', '0.23'])
Что я делаю, это скопировать этот столбец в новый столбец и сделать str.replace(‘.’, ”) и str.replace(‘,’, ”), после чего я выберу числовые значения.
и:
a = a.str.replace('.','')
a = a.str.replace(',','')
a.str.isnumeric()
Из [15]:
0 Неверно
1 Неверно
2 Правда
3 Истинный
4 Истинный
5 Правда
6 Правда
7 Правда
dtype: bool
Удачи всем!
Ответ №5
Я думаю что-то вроде
df[~df[''].str.contains('0|1|2|3|4|5|6|7|8|9')]
Просто отфильтровывать строки не содержит никакого числа?
Поскольку ТС так и не привел воспроизводимый пример, попробуем сами. Генерируем датафрейм, в котором ГДЕ-ТО есть значения «No»
import pandas as pd
data = [{'a': str(i), 'b': str(2 * i)} for i in range(5,8)]
data.append({'a':'1','b':'No'})
data.append({'a':'No','b':'9'})
df=pd.DataFrame(data)
print (df)
Имеем:
a b
0 5 10
1 6 12
2 7 14
3 1 No
4 No 9
Преобразовываем значения «No»во что хотим, для наглядности в 10000
def change_item(item):
if item=='No':
item = '10000'
return item
df = df.applymap(change_item)
print (df)
Получили
a b
0 5 10
1 6 12
2 7 14
3 1 10000
4 10000 9
Естественно, все значения пока символьные. Тепер
df_float=df.apply(pd.to_numeric)
Получили аналогичный датафрейм с типом данных float. И без ошибок преобразования.