Python 在Pandas查询中使用动态列表
举例来说,我有几个列编码不同类型的费率(Python 在Pandas查询中使用动态列表,python,pandas,Python,Pandas,举例来说,我有几个列编码不同类型的费率(“年费率”,“1/2年费率”,等等)。我想在我的数据框上使用query查找这些比率中任何一个都高于1的条目 首先,我找到要在查询中使用的列: cols = [x for ix, x in enumerate(df.columns) if 'rate' in x] 其中,例如,cols包含: ["annual rate", "1/2 annual rate", "monthly rate"] 然后我想做一些类似的事情: df.query('any of
“年费率”
,“1/2年费率”
,等等)。我想在我的数据框上使用query
查找这些比率中任何一个都高于1
的条目
首先,我找到要在查询中使用的列:
cols = [x for ix, x in enumerate(df.columns) if 'rate' in x]
其中,例如,cols
包含:
["annual rate", "1/2 annual rate", "monthly rate"]
然后我想做一些类似的事情:
df.query('any of my cols > 1')
我如何为
查询设置格式?类似的东西应该可以解决这个问题
df.query('|'.join('(%s > 1)' % col for col in cols))
但是我不知道如何处理列名中的空格,因此您可能必须重命名它们。query
执行Python表达式的完整解析(有一些限制,例如,您不能使用lambda
表达式或三元if
/else
表达式)。这意味着您在查询字符串中引用的任何列都必须是有效的Python标识符(更正式的“变量名”一词)。检查这一点的一种方法是使用标记化
模块中潜伏的名称
模式:
In [156]: tokenize.Name
Out[156]: '[a-zA-Z_]\\w*'
In [157]: def isidentifier(x):
.....: return re.match(tokenize.Name, x) is not None
.....:
In [158]: isidentifier('adsf')
Out[158]: True
In [159]: isidentifier('1adsf')
Out[159]: False
现在,由于列名中有空格,每个由空格分隔的单词都将作为单独的标识符进行计算,因此
df.query("annual rate > 1")
这是无效的Python语法。尝试在Python解释器中键入年率
,您将得到一个语法错误
异常
带回家的消息:将列重命名为有效的变量名。除非列遵循某种结构,否则您将无法以编程方式(至少很容易)完成此操作。在你的情况下,你可以这样做
In [166]: cols
Out[166]: ['annual rate', '1/2 annual rate', 'monthly rate']
In [167]: list(map(lambda x: '_'.join(x.split()).replace('1/2', 'half'), cols))
Out[167]: ['annual_rate', 'half_annual_rate', 'monthly_rate']
然后您可以设置查询字符串的格式,类似于@acushner的示例
In [173]: newcols
Out[173]: ['annual_rate', 'half_annual_rate', 'monthly_rate']
In [174]: ' or '.join('%s > 1' % c for c in newcols)
Out[174]: 'annual_rate > 1 or half_annual_rate > 1 or monthly_rate > 1'
注意:您实际上不需要在此处使用query
:
正如@Jeff在评论中指出的,您可以引用非标识符列名,尽管方式很笨拙:
pd.eval('df[df["annual rate"]>0]')
如果你想拯救小猫的生命,我不建议你写这样的代码。我得到了无效语法“(年率>1)或(月率>1)或(周率>1)或(日率>1)”
指向年率的末尾。你想使用'.
而不是或“
我想我也刚刚编辑过,不确定如何处理列中的空格。尝试重命名。谢谢。我尝试重命名时运气不佳:my_query=“'annual.rate'>1或'monthly.rate'>1或'weekly.rate'>1或'daily.rate'>1”
I getTypeError:data type“annual.rate”不理解“
@user815423426 Humm,在阅读文档后,似乎需要在原始数据框中重命名COL并执行查询。问题是pandas使用了一种修改过的python语法,因此它不能很好地处理空格、点或引号。请补充一点,您可以引用单个名称(仅使用eval),例如pd.eval('df[df[“年率”]>0])
工作(但有点笨拙)
pd.eval('df[df["annual rate"]>0]')