Сложные запросы к таблице в Pandas
Запросы к большой таблице в Pandas традиционными способами могут привести к нехватке оперативной памяти. Чтобы этого избежать, существует специальный синтаксис, о котором пойдет речь в данной статье.
Создадим датафрейм следующего вида:
df = pd.DataFrame([['Калашников', 'Павел', 'Москва', 15], ['Авдеева', 'Серафима', 'Новгород', 22], ['Магомедов', 'Ислам', 'Махачкала', 34], ['Павленко', 'Сергей', 'Киев', 45], ['Ибрагимов', 'Ислам', 'Махачкала', 77], ['Купеев', 'Павел', 'Москва', 21]],columns=['surname' ,'name', 'city', 'age']) df
Продемонстрируем распространенный способ задания сложного запроса:
df[(df['age']>25)&(df['surname'].isin(['Павленко', 'Ибрагимов']))&(df['name'].str.startswith('И'))]
В данном примере мы ищем лицо старше 25 лет с фамилией из списка и именем, начинающимся с "И". Если бы таблица весила несколько гигабайт на персональном компьютере могло не хватить памяти для обработки запроса, так как при такой индексации Pandas неявно создает несколько временных датафреймов: df['age']>25, df['surname'].isin(['Павленко', 'Ибрагимов']), df['name'].str.startswith('И'), а потом применяет к ним заданную логическую связку (в нашем случае "И"). Это имеет свои плюсы, в частности, ускоряет обработку на малых данных.
Альтернативным способом индексации является использование метода query. Так наш запрос бы выглядел с его применением:
df.query('age>25 & surname.isin(["Павленко", "Ибрагимов"]) & name.str.startswith("И")')
Как можно заметить, внутри метода на столбцы можно ссылаться по их имени. Также предусмотрен способ обращения к переменным пространства имен Python через символ @:
l = ['Павленко', 'Ибрагимов'] name_start = "И" df.query('age>25 & surname.isin(@l) & name.str.startswith(@name_start)')