Pandas: запросить пустой список

Основываясь на этом вопросе, мне удалось использовать метод запроса:

import pandas as pd
df = pd.DataFrame({"genre":[['comedy', 'sci-fi'], ['action', 'romance', 'comedy'], ['documentary'], ['crime','horror'], []]})
df.query("(genre.str.contains('comedy', na=False, regex=False))", engine = "python")

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

df.query("~(genre.str.contains('\\w*', na=False, regex=True))", engine = "python")

и многие другие варианты, но безуспешно…

Тем временем я успешно попробовал df.query("genre.astype('str') == '[]'"), но нахожу это уродливым хаком — преобразование в строку…

NBur 11.07.2024 17:27
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
98
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

IIUC, вы хотите вернуть строки, в которых список в столбце жанра пуст. Ты можешь сделать:

print(df)

                       genre
0           [comedy, sci-fi]
1  [action, romance, comedy]
2              [documentary]
3            [crime, horror]
4                         []

out = df.loc[df['genre'].str.len() == 0]
print(out)

  genre
4    []

Что это за колдовство? Есть ли какая-либо документация, почему str.len() (с использованием аксессора .str) будет рассматривать элементы серии как списки, а не строки?

DeepSpace 11.07.2024 17:24

Кстати, можешь пропустить .loc: print(df[df.genre.str.len() == 0])

DeepSpace 11.07.2024 17:25

Если подумать, имеет смысл, если панды слепо вызывают len на каждом объекте, очевидно, что и str, и list реализуют __len__. Если это так, то к этому ответу следует относиться с недоверием, поскольку он может или не может сломаться в будущей версии pandas.

DeepSpace 11.07.2024 17:30

@DeepSpace См. Строковые методы: «... методы, которые упрощают работу с каждым элементом массива». Обратите внимание, что здесь не написано «каждая строка». Затем позже: «Предупреждение: вообще говоря, метод доступа .str предназначен для работы только со строками. За очень немногими исключениями, другие варианты использования не поддерживаются и могут быть отключены позже».

wjandrea 11.07.2024 17:33

@wjandrea Это именно моя точка зрения. Спасибо, что отвез его домой :)

DeepSpace 11.07.2024 17:33

Спасибо, но, как уже упоминалось, мне бы хотелось query, чтобы поиграть с различными фильтрами.

NBur 11.07.2024 18:22

Вы можете использовать pandas взорвать, проверить, какая строка имеет значение na, и после этого использовать groupby Any, чтобы воссоздать исходный индекс.

m = df['genre'].explode().isna().groupby(level=0).any()
print(df[m])

Другой пример с использованием вашего условия:

m = (df['genre'].explode()
     .str.contains('\\w*', na=False, regex=True)
     .groupby(level=0).any()
    )
print(df[~m])

Результат:

genre
4   []

Спасибо, но, как уже упоминалось, мне бы хотелось query, чтобы поиграть с различными фильтрами.

NBur 11.07.2024 18:21

Вы можете фильтровать, используя тот же код. Я отредактирую, чтобы использовать то же условие

Triky 11.07.2024 18:34

Вы можете использовать apply для фильтрации кадра данных:

# option 1
df[df["genre"].apply(len) == 0]

# option 2
df[df["genre"].apply(lambda x: len(x) == 0)]

Вы можете сделать нечто подобное, используя query, ссылаясь на встроенную функцию len с локальной переменной и @:

len = len
df.query("genre.apply(@len) == 0")

Все печати:

  genre
4    []

Спасибо, но, как уже упоминалось, мне бы хотелось query, чтобы поиграть с различными фильтрами.

NBur 11.07.2024 18:21

@NBur Я обновил ответ возможным решением, используя query.

e-motta 11.07.2024 18:46

Вы можете проверить .str.len():

df.query('genre.str.len() == 0')

Выход:

  genre
4    []
Ответ принят как подходящий

Вы можете использовать ==, но для списка операция преобразуется в .isin, поэтому удвойте скобки:

>>> df.query('genre == [[]]')
  genre
4    []

Действительно, эквивалентно df[df['genre'].isin([[]])].

mozway 11.07.2024 19:51

Другие вопросы по теме