在赏金之前编辑:
我想要一个可以写subset(pd.dataframe,query="col %in% list_with_substrings")
的函数
其中它返回相同的数据帧,其中只有行包含col
list_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
只能访问其作用域中的变量,这意味着:
- 传递给函数的参数(
df
和query
) - 局部变量 (
query
) - 模块范围变量:(
pd
和subset
)
由于它是在那里计算的,因此它无法访问查询中提到的任何变量。
解决这个问题的简单方法,不是返回查询的结果,而是翻译后的查询。
这是一个解决方案,但唯一的疑问是您在测试文件中有多余的行,并且使用了不安全的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
没有变化.
它将按预期产生。