Фильтрация названий столбцов по первым символам (или по совпадению определенных символов)
Анализирую excel таблицу, в которой есть несколько листов, в заголовках которых отличается только одно название ячейки, а именно: название ячейки "Дата пост.ф.1.2" отличается от названия аналогичной по содержанию ячейки в другом листе "Дата пост.ф.1" (в последней имя ячейки короче на 1 символ). Пример кода:
import pandas as pd
sheet = input('Введите номер интересующей страницы: ')
sheet_result = 'Данные_' + str(sheet)
dd = pd.read_excel('test.xlsx', sheet_name=sheet_result)
result = dd.query('`Дата пост.ф.1.2`.notnull() == True') # фильтр ненулевых значений
print(len(result['Район']))
При выборе таблицы, в которой имя ячейки отличается от "Дата пост.ф.1.2" выдается ожидаемая ошибка:
pandas.core.computation.ops.UndefinedVariableError:
name 'BACKTICK_QUOTED_STRING_Дата_пост_DOT_ф_DOT_1_DOT_2' is not defined
Вопрос: как сделать аналогичную конструкцию через метод query() (или в случае невозможности использовать указанный метод - альтернативный), где при выборе имени ячейки будет проверяться неполное совпадение по названию, а частичное, например "Дата пост" или "Дата пост.ф". Конструкции if, else не хочется применять, т.к. страдает гибкость и в случае изменения исходных названий ячеек возникнут проблемы...
Ответы (1 шт):
Метод DataFrame.query() не позволяет работать с именами столбцов, в которых встречаются символ точки или другие символы пунктуации или специальные символы.
В Pandas можно воспользоваться другими методами.
Пример:
Исходный DF:
In [15]: df
Out[15]:
col 1 col 1.2 col 1.3 col 2 col2.1
0 3 4 4 1 9
1 1 7 0 0 0
2 7 7 2 2 0
3 4 3 0 1 5
4 0 7 9 5 5
In [16]: df.columns
Out[16]: Index(['col 1', 'col 1.2', 'col 1.3', 'col 2', 'col2.1'], dtype='object')
выбираем столбцы начинающиеся со строки "col 1":
In [17]: df.columns.str.contains(r"^col 1")
Out[17]: array([ True, True, True, False, False])
In [18]: df.columns[df.columns.str.contains(r"^col 1")]
Out[18]: Index(['col 1', 'col 1.2', 'col 1.3'], dtype='object')
In [19]: df.loc[:, df.columns.str.contains(r"^col 1")]
Out[19]:
col 1 col 1.2 col 1.3
0 3 4 4
1 1 7 0
2 7 7 2
3 4 3 0
4 0 7 9
Если нужен соответствующий DF (подмножество исходного DF с отобранными столбцами), то можно воспользоваться методом DataFrame.filter():
In [20]: df.filter(like="col 1")
Out[20]:
col 1 col 1.2 col 1.3
0 3 4 4
1 1 7 0
2 7 7 2
3 4 3 0
4 0 7 9
In [21]: df.filter(regex="^col 1")
Out[21]:
col 1 col 1.2 col 1.3
0 3 4 4
1 1 7 0
2 7 7 2
3 4 3 0
4 0 7 9
выберем все столбцы содержащие точку в названии:
In [22]: df.filter(regex="\.")
Out[22]:
col 1.2 col 1.3 col2.1
0 4 4 9
1 7 0 0
2 7 2 0
3 3 0 5
4 7 9 5