Функция, содержащая запрос панд, не может найти локальную переменную, только если импортирована - PullRequest
4 голосов
/ 04 мая 2019

РЕДАКТИРОВАТЬ ДО BOUNTY:

Я хотел бы иметь функцию, где я могу написать subset(pd.dataframe,query="col %in% list_with_substrings")

, где он возвращает тот же кадр данных, где только строки содержат любыеподстрок в list_with_substrings для col.

Как будто я написал: dataframe.query("col in @list_with_substring")

И должна быть возможность импортировать эту функцию в другой скрипт, и не иметьпереопределить функцию каждый раз, когда она используется.Если переопределение является единственной опцией, то это должно быть сделано внутри самой функции.Так что вызов подмножества - это одна строка.

Исходное сообщение:

У меня есть два сценария:

"dataprocessing.py"

import pandas as pd
def subset(df,query):
    query = query.replace("%in%", "in @")
    query = query.replace("%!in%", "not in @")     
    return pd.DataFrame(df.query(query))

и "test_dataprocessing.py "

from dataprocessing import *

df = pd.DataFrame({'countries':['US','UK','GE','Ch',"DK","SW"]})
countries_to_subset = ['UK','CH']

subset(df,query="countries %in% countries_to_subset")

Это приводит к ошибке:

pandas.core.computation.ops.UndefinedVariableError: локальная переменная 'country_to_subset' не определена

, но если я тогдаопределить функцию внутри того же сценария

def subset(df,query):
    query = query.replace("%in%", "in @")
    query = query.replace("%!in%", "not in @")
    return pd.DataFrame(df.query(query))

subset(df,query="countries %in% countries_to_subset")

Out: 
  countries  GDP
1        UK    2
3     China    4

Поэтому я не могу импортировать функцию, которая использует запрос, и передать ее локальной переменной?Есть ли способ импортировать функцию подмножества «как если бы» она была определена в том же скрипте?

протестировано на Python 3.6 и 3.7 и пандах 0.23.0 и 0.24.2

Ответы [ 3 ]

2 голосов
/ 04 мая 2019

Похоже, проще всего использовать f-strings:

dataprocessing.py

import pandas as pd


def subset(df,query):
    query = query.replace("%in%", "in") # remove @
    query = query.replace("%!in%", "not in") # remove @
    return pd.DataFrame(df.query(query))

test_dataprocessing.py

import pandas as pd
from dataprocessing import *


df = pd.DataFrame({'countries':['US','UK','GE','Ch',"DK","SW"]})
countries_to_subset = ['UK','CH']

subset(df, query=f"countries %in% {countries_to_subset}")
1 голос
/ 17 мая 2019

Это происходит потому, что вы оцениваете запрос в subset. subset имеет доступ только к переменным в своей области, что означает:

  • параметры, переданные в функцию (df и query)
  • локальные переменные (query)
  • переменные области видимости модуля: (pd и subset)

Поскольку он оценивается там, он не имеет доступа ни к одной из переменных, упомянутых в запросе.

Простой способ решить эту проблему, вместо того, чтобы возвращать результат запроса, переведенный запрос.

0 голосов
/ 17 мая 2019

Вот решение, но единственное сомнение в том, что у вас есть дополнительные строки в файле тестирования, и используется небезопасное exec.

test_dataprocessing.py:

import inspect
exec(inspect.getsource(__import__('dataprocessing')))

df = pd.DataFrame({'countries':['US','UK','GE','Ch',"DK","SW"]})
countries_to_subset = ['UK','CH']

subset(df,query="countries %in% countries_to_subset")

Ибез изменений с dataprocessing.py.

Результат будет, как и ожидалось.

...