Панды: строка запроса, где имя столбца содержит специальные символы

Я работаю с фреймом данных, который имеет структуру что-то вроде следующего:

In[75]: df.head(2)
Out[75]: 
  statusdata             participant_id association  latency response  \
0   complete  CLIENT-TEST-1476362617727       seeya      715  dislike   
1   complete  CLIENT-TEST-1476362617727      welome      800     like   

   stimuli elementdata statusmetadata demo$gender  demo$question2  \
0  Sample B    semi_imp       complete        male              23   
1  Sample C    semi_imp       complete      female              23   

Я хочу иметь возможность запустить строку запроса к столбцу demo$gender,

То есть,

df.query("demo$gender=='male'")

Но это проблема с $ знак. Если я заменю $ подписать с другим разделителем (как -) тогда проблема сохраняется. Могу ли я исправить строку запроса, чтобы избежать этой проблемы. Я бы предпочел не переименовывать столбцы, поскольку они тесно связаны с другими частями моего приложения.

Я действительно хочу придерживаться строки запроса, поскольку она предоставляется другим компонентом нашего стека технологий, и создание синтаксического анализатора было бы тяжелой задачей для того, что кажется простой проблемой.

Заранее спасибо.

3 ответа

Решение

Текущая реализация query требует, чтобы строка была допустимым выражением Python, поэтому имена столбцов должны быть действительными идентификаторами Python. Вы можете переименовать столбец или использовать простой логический фильтр, например так:

df[df['demo$gender'] =='male']

В актуальной версии pandas вы можете скрыть имя столбца с помощью обратной кавычки (`)

      df.query("`demo$gender` == 'male'")

Другая возможность - очистить имена столбцов в качестве предыдущего шага в вашем процессе, заменив специальные символы некоторыми другими, более подходящими.

Например:

      (df
 .rename(columns = lambda value: value.replace('$', '_'))
 .query("demo_gender == 'male'")
) 

Для интересующихся вот простая процедура, которую я использовал для выполнения задачи:

# Identify invalid column names
invalid_column_names = [x for x in list(df.columns.values) if not x.isidentifier() ]

# Make replacements in the query and keep track
# NOTE: This method fails if the frame has columns called REPL_0 etc.
replacements = dict()
for cn in invalid_column_names:
    r = 'REPL_'+ str(invalid_column_names.index(cn))
    query = query.replace(cn, r)
    replacements[cn] = r

inv_replacements = {replacements[k] : k for k in replacements.keys()}

df = df.rename(columns=replacements) # Rename the columns
df  = df.query(query) # Carry out query

df = df.rename(columns=inv_replacements)

Что означает идентификацию неверных имен столбцов, преобразование запроса и переименование столбцов. Наконец мы выполняем запрос и затем переводим имена столбцов обратно.

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