Сложные запросы к таблице в 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)')