Python以字符串形式执行操作

Python以字符串形式执行操作,python,pandas,conditional-statements,Python,Pandas,Conditional Statements,因此,我试图将一个变量操作(用户定义的)传递到一个函数中,但在尝试找到一个好的方法时遇到了困难。我所能想到的就是将所有选项硬编码到函数中,如下所示: def DoThings(Conditions): import re import pandas as pd d = {'time' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd']), 'legnth' : pd.Series([4., 5., 6., 7.], inde

因此,我试图将一个变量操作(用户定义的)传递到一个函数中,但在尝试找到一个好的方法时遇到了困难。我所能想到的就是将所有选项硬编码到函数中,如下所示:

def DoThings(Conditions):
import re
import pandas as pd
d = {'time' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd']),
     'legnth' : pd.Series([4., 5., 6., 7.], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
print df

for Condition in Conditions:
    # Split the condition into two parts
    SplitCondition = re.split('<=|>=|!=|<|>|=',Condition)

    # If the right side of the conditional statement is a number convert it to a float
    if SplitCondition[1].isdigit():
        SplitCondition[1] = float(SplitCondition[1])

    # Perform the condition specified
    if "<=" in Condition:
        df = df[df[SplitCondition[0]]<=SplitCondition[1]]
        print "one"
    elif ">=" in Condition:
        df = df[df[SplitCondition[0]]>=SplitCondition[1]]
        print "two"
    elif "!=" in Condition:
        df = df[df[SplitCondition[0]]!=SplitCondition[1]]
        print "three"
    elif "<" in Condition:
        df = df[df[SplitCondition[0]]<=SplitCondition[1]]
        print "four"
    elif ">" in Condition:
        df = df[df[SplitCondition[0]]>=SplitCondition[1]]
        print "five"
    elif "=" in Condition:
        df = df[df[SplitCondition[0]]==SplitCondition[1]]
        print "six"
return df

# Specify the conditions
Conditions = ["time>2","legnth<=6"]
df = DoThings(Conditions)   # Call the function

print df
这一切都很好,但我想知道是否有更好或更有效的方法将条件传递到函数中,而无需写出所有可能的if语句。有什么想法吗

解决方案:

def DoThings(Conditions):
    import re
    import pandas as pd
    d = {'time' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd']),
         'legnth' : pd.Series([4., 5., 6., 7.], index=['a', 'b', 'c', 'd'])}
    df = pd.DataFrame(d)
    print df

    for Condition in Conditions:
        # Split the condition into two parts
        SplitCondition = re.split('<=|>=|!=|<|>|=',Condition)

        # If the right side of the conditional statement is a number convert it to a float
        if SplitCondition[1].isdigit():
            SplitCondition[1] = float(SplitCondition[1])

        import operator
        ops = {'<=': operator.le, '>=': operator.ge, '!=': operator.ne, '<': operator.lt, '>': operator.gt, '=': operator.eq}
        cond = re.findall(r'<=|>=|!=|<|>|=', Condition)
        df = df[ops[cond[0]](df[SplitCondition[0]],SplitCondition[1])]

    return df



# Specify the conditions
Conditions = ["time>2","legnth<=6"]
df = DoThings(Conditions)   # Call the function

print df

您可以通过
operator
模块访问内置运算符,然后构建一个表,将您的运算符名称映射到内置运算符,如下面的简化示例所示:

import operator
ops = {'<=': operator.le, '>=': operator.ge}

In [3]: ops['>='](2, 1)
Out[3]: True
导入操作符
ops={'=':operator.ge}
[3]中:ops['>='](2,1)
Out[3]:正确

您可以通过
操作符
模块访问内置操作符,然后构建一个表,将您的操作符名称映射到内置操作符,如下面的简化示例所示:

import operator
ops = {'<=': operator.le, '>=': operator.ge}

In [3]: ops['>='](2, 1)
Out[3]: True
导入操作符
ops={'=':operator.ge}
[3]中:ops['>='](2,1)
Out[3]:正确
您可以使用来执行此类操作(您会发现速度要快得多):

您可以使用来执行此类操作(您会发现速度要快得多):


pandas==0.13
(不确定该版本何时发布…
0.12
)中,您将能够执行以下操作,所有这些操作都是等效的:

res = df.query('(legnth == 4) | (time == 4)')
res = df.query('legnth == 4 | time == 4')
res = df.query('legnth == 4 or time == 4')
我个人最喜欢的

res = df['legnth == 4 or time == 4']

query
\uuuuu getitem\uuuu
都接受任意布尔表达式,并在表达式中的每个变量名上自动“前缀”调用帧实例(也可以使用局部变量和全局变量)。这使您能够1)比在所有内容前面键入
df.
更简洁地表达查询2)使用语法表达查询,让我们面对现实,这种语法看起来比难看的按位运算符更好,3)如果您有巨大的帧和非常复杂的表达式,则可能比“纯”Python等价物快得多,最后4)允许您将同一查询传递到多个帧(毕竟,它是一个字符串),并具有公共列子集。

pandas==0.13
(不确定该版本何时发布…
0.12
刚刚发布)您将能够执行以下操作,所有操作都是等效的:

res = df.query('(legnth == 4) | (time == 4)')
res = df.query('legnth == 4 | time == 4')
res = df.query('legnth == 4 or time == 4')
我个人最喜欢的

res = df['legnth == 4 or time == 4']

query
\uuuuu getitem\uuuu
都接受任意布尔表达式,并在表达式中的每个变量名上自动“前缀”调用帧实例(也可以使用局部变量和全局变量)。这使您能够1)比在所有内容前面键入
df.
更简洁地表达查询2)使用语法表达查询,让我们面对现实,这种语法看起来比难看的按位运算符更好,3)如果您有巨大的帧和非常复杂的表达式,则可能比“纯”Python等价物快得多,最后4)允许您将相同的查询传递给多个框架(毕竟,它是一个字符串),其中包含一个共同的列子集。

这正是我想要的。谢谢答案在问题中实现。虽然这回答了OP(或任何其他在这里绊倒的人)是如何做到这一点的。。。他们真的不应该推出他们自己的(效率较低的)numpy掩蔽。@AndyHayden:“其他在这里遇到麻烦的人”可能没有使用numpy——他们可能只是在寻找一种简洁的方法来实现一组操作符。回过头来看,我仍然认为创建DSL来实现这一点是个坏主意……这正是我想要的。谢谢答案在问题中实现。虽然这回答了OP(或任何其他在这里绊倒的人)是如何做到这一点的。。。他们真的不应该推出他们自己的(效率较低的)numpy掩蔽。@AndyHayden:“其他在这里遇到麻烦的人”可能没有使用numpy——他们可能只是在寻找一种简洁的方法来实现一组操作符。回过头来看,我仍然认为OP创建一个DSL来实现这一点是一个坏主意……在上面的例子中,您将如何实现这一点?在pandas 0.13中,您将能够使用
df['legnth==4或time==4']
方法对
DataFrame
对象和
pd.eval
执行
,在引擎盖下使用
numexpr
的顶级计算器。@cpcloud您肯定应该用它添加一个新答案。:)太棒了!在上面的示例中,您将如何实现这一点?在pandas 0.13中,您将能够通过
DataFrame
对象和
pd.eval
上的
query
方法执行
df['legnth==4或time==4']
,在引擎盖下使用
numexpr
的顶级计算器。@cpcloud您肯定应该用它添加一个新答案。:)太棒了!
res = df['legnth == 4 or time == 4']