У меня есть DataFrame pandas, и я хочу удалить из него строки, где длина строки в определенном столбце больше 2.
Я ожидаю, что смогу сделать это (за этот ответ ):
df[(len(df['column name']) < 2)]
но я просто получаю ошибку:
KeyError: u'no item named False'
Что я делаю не так?
(Примечание: я знаю, что могу использовать, df.dropna()
чтобы избавиться от строк, которые их содержат NaN
, но я не видел, как удалить строки на основе условного выражения.)
df[[(len(x) < 2) for x in df['column name']]]
но у тебя гораздо приятнее. Спасибо за вашу помощь!df[df['column name'].map(lambda x: str(x)!=".")]
pandas 0.23.4
и Python 3.6.copy()
в конце, на случай, если вы захотите позже отредактировать этот фрейм данных (например, назначение новых столбцов вызовет предупреждение «Значение пытается быть скопировано с копии среза из фрейма данных».Чтобы напрямую ответить на оригинальный заголовок этого вопроса «Как удалить строки из DataFrame pandas на основе условного выражения» (что, как я понимаю, не обязательно является проблемой OP, но может помочь другим пользователям, сталкивающимся с этим вопросом), один из способов сделать это - использовать падение метод:
df = df.drop(some labels)
df = df.drop(df[<some boolean condition>].index)
пример
Чтобы удалить все строки, в которых столбец «Score» <50:
df = df.drop(df[df.score < 50].index)
Версия на месте (как указано в комментариях)
df.drop(df[df.score < 50].index, inplace=True)
Несколько условий
(см. логическое индексирование )
Чтобы удалить все строки, где столбец «оценка» <50 и> 20
df = df.drop(df[(df.score < 50) & (df.score > 20)].index)
источник
reset_index()
). Я нашел это трудным путем, когда из моего кадра данных пропал путь ко многим строкам.test = df.drop(df[df['col1'].dtype == str].index)
но я получаю ошибкуKeyError: False
я также попробовалdf.drop(df[df.col1.dtype == str].index)
и ,df.drop(df[type(df.cleaned_norm_email) == str].index)
но ничего не похоже на работу? Может кто-нибудь посоветовать. Спасибо! @Userdf[(df.score < 50) & (df.score > 20)]
как часть вашего ответа. Если вы измените это,df = df[(df.score >= 50) | (df.score <= 20)]
вы получите свой ответ намного быстрее.Вы можете назначить
DataFrame
отфильтрованную версию себя:Это быстрее чем
drop
:источник
Я буду расширять общее решение @ User, чтобы обеспечить
drop
бесплатную альтернативу. Это для людей, которых здесь направляют, основываясь на названии вопроса (не проблема ОП)Скажем, вы хотите удалить все строки с отрицательными значениями. Одно решение лайнера является: -
Пошаговое объяснение: -
Давайте сгенерируем случайный кадр данных нормального распределения 5x5
Пусть условие удаляет негативы. Логическое значение df, удовлетворяющее условию:
Булева серия для всех строк, удовлетворяющих условию. Примечание. Если какой-либо элемент в строке не соответствует условию, строка помечается как ложная.
Наконец, отфильтруйте строки из фрейма данных на основе условия
Вы можете назначить его обратно в df, чтобы фактически удалить против фильтрации, выполненной выше
df = df[(df > 0).all(axis=1)]
Это может быть легко расширено для фильтрации строк, содержащих NaN (не числовые записи): -
df = df[(~df.isnull()).all(axis=1)]
Это также может быть упрощено для случаев, таких как: Удалить все строки, где столбец E является отрицательным
Я хотел бы закончить некоторыми статистическими данными о том, почему
drop
решение @ User медленнее, чем простая фильтрация на основе столбцов:Столбец - это массив,
Series
то естьNumPy
он может быть проиндексирован без каких-либо затрат. Для людей, интересующихся тем, как основная организация памяти влияет на скорость выполнения, вот отличная ссылка на ускорение работы Pandas :источник
В пандах вы можете
str.len
использовать границы и использовать логический результат для его фильтрации.источник
Если вы хотите отбросить строки фрейма данных на основе некоторого сложного условия в значении столбца, то запись, как показано выше, может быть сложной. У меня есть следующее простое решение, которое всегда работает. Предположим, что вы хотите удалить столбец с заголовком, поэтому сначала поместите этот столбец в список.
Теперь примените некоторую функцию к каждому элементу списка и поместите его в серию панда:
в моем случае я просто пытался получить количество токенов:
Теперь добавьте один дополнительный столбец с указанными выше рядами во фрейм данных:
Теперь мы можем применить условие к новому столбцу, например:
источник