1

そのため、変数操作 (ユーザー定義) を関数に渡そうとしていますが、それを行う良い方法を見つけるのに苦労しています。私が考えることができるのは、次のようにすべてのオプションを関数にハードコーディングすることだけです:

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

これにより、次のようになります。

   legnth  time
a       4     1
b       5     2
c       6     3
d       7     4
five
one
   legnth  time
c       6     3

これはすべてうまくいっていますが、可能性のあるすべての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

出力:

   legnth  time
a       4     1
b       5     2
c       6     3
d       7     4
   legnth  time
c       6     3
4

3 に答える 3

2

マスキングを使用して、この種の操作を行うことができます (はるかに高速です)。

In [21]: df[(df.legnth <= 6) & (df.time > 2)]
Out[21]:
   legnth  time
c       6     3

In [22]: df[(df.legnth <= 6) & (df.time >= 2)]
Out[22]:
   legnth  time
b       5     2
c       6     3

注: クエリに b を含めてはならないため、実装にバグがあります。

または (を使用して|) 操作を実行することもできます。これは期待どおりに機能します。

In [23]: df[(df.legnth == 4) | (df.time == 4)]
Out[23]:
   legnth  time
a       4     1
d       7     4
于 2013-05-13T17:33:20.097 に答える
0

(その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どちらも任意のブール式を__getitem__受け入れ、式の各変数名に呼び出しフレーム インスタンスを自動的に「プレフィックス」します (ローカルとグローバルも使用できます)。これにより、1) すべての前に入力するよりも少し簡潔にクエリを表現することができますdf.。2) 見栄えの悪いビット演算子よりも見栄えの良い構文を使用してクエリを表現することができます。3) 「純粋な」Python の同等物よりも潜在的にはるかに高速です。巨大なフレームと非常に複雑な式があり、最後に 4) を使用すると、共通の列のサブセットを使用して同じクエリを複数のフレーム (結局のところ、文字列です) に渡すことができます。

于 2013-07-29T02:28:34.527 に答える