Попытка удалить NaN индексированную строку в dataframe
Я использую python 2.7.3 и Pandas версии 0.12.0.
Я хочу удалить строку с индексом NaN, чтобы у меня были только допустимые значения site_id.
print df.head()
special_name
site_id
NaN Banana
OMG Apple
df.drop(df.index[0])
TypeError: 'NoneType' object is not iterable
Если я попытаюсь сбросить диапазон, например:
df.drop(df.index[0:1])
Я получаю эту ошибку:
AttributeError: 'DataFrame' object has no attribute 'special_name'
6 ответов
Я обнаружил, что самый простой способ-сбросить индекс, удалить NaNs, а затем снова сбросить индекс.
In [26]: dfA.reset_index()
Out[26]:
index special_name
0 NaN Apple
1 OMG Banana
In [30]: df = dfA.reset_index().dropna().set_index('index')
In [31]: df
Out[31]:
special_name
index
OMG Banana
С версией pandas >= 0.20.0 вы можете:
df[df.index.notnull()]
версия:
df[pandas.notnull(df.index)]
чтобы сломать его:
notnull
генерирует логическую маску, например [False, False, True]
, где True означает, что значение в соответствующей позиции равно null (numpy.nan
или None
). Затем мы выбираем строки, индекс которых соответствует истинному значению в маске, используя df[boolean_mask]
.
Проверено это работает :
df.reset_index(inplace=True)
df.drop(df[df['index'].isnull()].index, inplace=True)
как я проверил выше
Реплицировал таблицу в исходном вопросе, используя
df=pd.DataFrame(data=['Banana', 'Apple'], index=[np.nan, 'OMG'],columns=['Special_name'])
затем введите вышеуказанные две строки кода, которые я пытаюсь объяснить на человеческом языке ниже:
- 1-я строка сбрасывает индекс на целые числа, и NaN теперь находится в столбце с именем исходного имени индекса ("index" в примере выше поскольку имя не было указано) - pandas делает это автоматически с помощью команды reset_index ().
- 2-я строка из самых внутренних скобок:
df[df['index'].isnull()]
фильтрует строки, для которых столбец с именем "index" показывает значения " NaN " с помощью команды isnull ()..index
используется для передачи однозначного объекта индекса, указывающего на все строки "index" =NaN вdf.drop(
в самой внешней части выражения.
nb: протестировал вышеуказанную команду для работы с несколькими значениями NaN в a колонка
использование Python 3.5.1, Pandas 0.17.1 через пакет Anaconda 32bits
ни один из ответов не работал 100% для меня. Вот что получилось:
In [26]: print df
Out[26]:
site_id special_name
0 OMG Apple
1 NaN Banana
2 RLY Orange
In [27]: df.dropna(inplace=True)
Out[27]:
site_id special_name
0 OMG Apple
2 RLY Orange
In [28]: df.reset_index(inplace=True)
Out[28]:
index site_id special_name
0 0 OMG Apple
1 2 RLY Orange
In [29]: df.drop('index', axis='columns', inplace=True)
Out[29]:
site_id special_name
0 OMG Apple
1 RLY Orange
Edit: следующее, вероятно, относится только к MultiIndex
S, и в любом случае заменен на новый (см. другие ответы). Я оставлю этот ответ только для исторического интереса.
для людей, которые приходят к этому сейчас, можно сделать это напрямую, без переиндексации, опираясь на тот факт, что Нанс в индексе будет представлено с меткой -1
. Итак:
df = dfA[dfA.index.labels!=-1]
еще лучше, в Pandas>0.16.1, можно использовать drop (), чтобы сделать это на месте без копирования:
dfA.drop(labels=[-1], level='index', inplace=True)
NB: немного вводит в заблуждение, что уровень индекса называется "index": обычно это будет что-то более специфичное для использования, например "date" или "experimental_run"..
по состоянию на pandas
0.19, Index
es есть .notnull()
метод, поэтому ответ timdiels можно упростить до:
df[df.index.notnull()]
который, я думаю, (в настоящее время) самый простой, который вы можете получить.