249

次のデータフレームで複数の列を使用する場合、パンダの適用機能に問題があります

df = DataFrame ({'a' : np.random.randn(6),
                 'b' : ['foo', 'bar'] * 3,
                 'c' : np.random.randn(6)})

そして次の関数

def my_test(a, b):
    return a % b

この関数を次のように適用しようとすると:

df['Value'] = df.apply(lambda row: my_test(row[a], row[c]), axis=1)

エラーメッセージが表示されます:

NameError: ("global name 'a' is not defined", u'occurred at index 0')

このメッセージがわかりません。名前を適切に定義しました。

この問題について何か助けていただければ幸いです

アップデート

ご協力いただきありがとうございます。私は確かにコードでいくつかの構文ミスを犯しました。インデックスは '' にする必要があります。ただし、次のようなより複雑な関数を使用しても同じ問題が発生します。

def my_test(a):
    cum_diff = 0
    for ix in df.index():
        cum_diff = cum_diff + (a - df['a'][ix])
    return cum_diff 
4

6 に答える 6

33

(列 a) % (列 b) を計算するだけの場合は、 は必要ありませんapply。直接実行してください。

In [7]: df['a'] % df['c']                                                                                                                                                        
Out[7]: 
0   -1.132022                                                                                                                                                                    
1   -0.939493                                                                                                                                                                    
2    0.201931                                                                                                                                                                    
3    0.511374                                                                                                                                                                    
4   -0.694647                                                                                                                                                                    
5   -0.023486                                                                                                                                                                    
Name: a
于 2013-05-03T07:56:43.013 に答える
11

上記の提案はすべて機能しますが、計算をより効率的にしたい場合は、numpy ベクトル演算を利用する必要があります(ここで指摘されているように)

import pandas as pd
import numpy as np


df = pd.DataFrame ({'a' : np.random.randn(6),
             'b' : ['foo', 'bar'] * 3,
             'c' : np.random.randn(6)})

例 1: でループpandas.apply():

%%timeit
def my_test2(row):
    return row['a'] % row['c']

df['Value'] = df.apply(my_test2, axis=1)

最も遅い実行は、最も速い実行よりも 7.49 倍長くかかりました。これは、中間結果がキャッシュされていることを意味する場合があります。1000 ループ、ベストオブ 3: ループあたり 481 µs

例 2: 次を使用してベクトル化しpandas.apply()ます。

%%timeit
df['a'] % df['c']

最も遅い実行は、最も速い実行よりも 458.85 倍長くかかりました。これは、中間結果がキャッシュされていることを意味する場合があります。10000 ループ、ベストオブ 3: ループあたり 70.9 µs

例 3: numpy 配列を使用したベクトル化:

%%timeit
df['a'].values % df['c'].values

最も遅い実行は、最も速い実行よりも 7.98 倍長くかかりました。これは、中間結果がキャッシュされていることを意味する場合があります。100000 ループ、ベストオブ 3: ループあたり 6.39 µs

そのため、numpy 配列を使用してベクトル化すると、速度がほぼ 2 桁向上しました。

于 2018-04-27T21:14:48.220 に答える