包含熊猫查询的函数只有在导入时才能找到局部变量



在赏金之前编辑:

我想要一个可以写subset(pd.dataframe,query="col %in% list_with_substrings")的函数

其中它返回相同的数据帧,其中只有行包含collist_with_substrings中的任何子字符串。

好像我写过: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.computing.ops.UndefinedVariableError: 局部变量 'countries_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以及pandas 0.23.0和0.24.2上进行了测试

看起来最简单的方法是使用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}")

发生这种情况是因为您在subset中评估查询。subset只能访问其作用域中的变量,这意味着:

  • 传递给函数的参数(dfquery)
  • 局部变量 (query)
  • 模块范围变量:(pdsubset)

由于它是在那里计算的,因此它无法访问查询中提到的任何变量。

解决这个问题的简单方法,不是返回查询的结果,而是翻译后的查询。

这是一个解决方案,但唯一的疑问是您在测试文件中有多余的行,并且使用了不安全的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没有变化.

它将按预期产生。

最新更新