2015-11-18 7 views
5

私は約100列と200000行のデータを含むpandas.DataFrameオブジェクトを持っています。私はboolデータフレームに変換しようとしています。ここで、Trueは値がしきい値よりも大きいことを意味し、Falseはそれがより少なく、NaN値が維持されることを意味します。pandasデータフレーム不等式でNaNを保持する

何のNaN値がない場合、それは私が実行するために約60ミリ秒かかる:

df >= threshold 

をしかし、私はNaNを扱うしようとすると、以下の方法で動作しますが、非常に遅い(20秒)。

def func(x): 
    if x >= threshold: 
     return True 
    elif x < threshold: 
     return False 
    else: 
     return x 
df.apply(lambda x: x.apply(lambda x: func(x))) 

速い方法がありますか?

+0

:以下のタイミングは200Kの長さの配列xです。なぜあなたは2つの 'lambda x'を割り当てましたか? 'df.apply(func)'はこのトリックを行います。 – DeepSpace

+0

@DeepSpaceと同じ時間がかかりました – jsignell

答えて

3

あなたが行うことができます。

new_df = df >= threshold 
new_df[df.isnull()] = np.NaN 

しかし、それはあなたが法を適用し使用し得るものと異なっています。ここでマスクにはNaN、0.0と1.0を含むfloat dtypeがあります。適用ソリューションでは、object dtypeをNaN、False、およびTrueで取得します。

あなたが望むものが得られない可能性があるため、マスクとして使用することもできません。 IEEEでは、NaNの比較はFalseを返さなければならず、applyメソッドは暗黙のうちにNaN!

最適なオプションは、NaNを別々に追跡することです。ボトルネックがインストールされている場合、df.isnull()は非常に高速です。

+0

https://pypi.python org/pypi/Bottleneck –

1

あなたは別に、このポストを使用してNaNのためにチェックすることができます。Python - find integer index of rows with NaN in pandas

df.isnull() 

ビット単位を使用してdf >= thresholdisnullの出力を組み合わせるか:あなたは二つのマスクがに近づく取ることを期待することができ

df.isnull() | df >= threshold 

計算と結合には200msが必要ですが、それは20秒から十分離れてOKになるはずです。

+0

それらを組み合わせる方法についてのアイデアはありますか?それは私が下に行く必要があると思う道です。 – jsignell

+0

更新された回答。 –

+0

これは私には役に立たなかった。私はpython 2.7.1、pandas 0.17.0(通常私が使用しているもの)で試して、NotImplementedErrorを取得しました。次にpython 3.4.3、pandas 0.17.0で試してみました。そして、 'bitwise_or'は入力タイプ – jsignell

0

この状況では、0 = False、1 = True、NaN = missingのようなfloatのインジケータ配列を使用します。 bool dtypeのPandas DataFrameには値がない可能性があり、object dtypeのDataFrameにはPython boolとfloatオブジェクトが混在しています。これにより、np.float64 dtypeのDataFramesが使用されます。 numpy.sign(x - threshold)は、比較のために-1 =(x <のしきい値)、0 =(x == threshold)と+1 =(x>しきい値)を与えます。その変換をインプレースで行うことができます。 xはなし他のX 'でない場合、それはより速くかもしれない `リターンのx> =しきい値:この行で、あなたの` func`を交換してみ

In [45]: %timeit y = (x > 0); y[pd.isnull(x)] = np.nan 
100 loops, best of 3: 8.71 ms per loop 

In [46]: %timeit y = np.sign(x) 
100 loops, best of 3: 1.82 ms per loop 

In [47]: %timeit y = np.sign(x); y += 1; y /= 2 
100 loops, best of 3: 3.78 ms per loop 
+0

上記の3つのアプローチは全て、dtype 'np.float64'を持つDataFrame yを与え、すべてのNaNを保存していることを述べておきます。 2番目のアプローチでは、False/Trueに対して-1/1コーディングを行い、その他は0/1コーディングを行います。 'y =(1 + np.sign(x))/ 2'も競争力がある。 –

+0

これは、正確な平等があるときに、あなたが望むものを与えないかもしれません。 'np.sign(x - threshold)'は 'x == threshold 'なら0になりますので、最終結果ではx = thresholdなら1、x> thresholdなら1となります。等価性が可能ならば、 'e = np.finfo(np.float64).eps'のところで' y =(1 + np.sign(eps + x - threshold))/ 2'を使うことができます。 –

関連する問題