web-dev-qa-db-ja.com

ラムダ関数をpandasデータフレーム列に適切に適用する方法

pandasデータフレームsampleがあり、PRと呼ばれる列の1つにラムダ関数を次のように適用しています。

sample['PR'] = sample['PR'].apply(lambda x: NaN if x < 90)

次に、次の構文エラーメッセージが表示されます。

sample['PR'] = sample['PR'].apply(lambda x: NaN if x < 90)
                                                         ^
SyntaxError: invalid syntax

私は何を間違えていますか?

20
Amani

mask が必要です:

sample['PR'] = sample['PR'].mask(sample['PR'] < 90, np.nan)

loc および boolean indexing を使用した別のソリューション:

sample.loc[sample['PR'] < 90, 'PR'] = np.nan

サンプル:

import pandas as pd
import numpy as np

sample = pd.DataFrame({'PR':[10,100,40] })
print (sample)
    PR
0   10
1  100
2   40

sample['PR'] = sample['PR'].mask(sample['PR'] < 90, np.nan)
print (sample)
      PR
0    NaN
1  100.0
2    NaN
sample.loc[sample['PR'] < 90, 'PR'] = np.nan
print (sample)
      PR
0    NaN
1  100.0
2    NaN

編集:

applyを使用したソリューション:

sample['PR'] = sample['PR'].apply(lambda x: np.nan if x < 90 else x)

タイミングlen(df)=300k

sample = pd.concat([sample]*100000).reset_index(drop=True)

In [853]: %timeit sample['PR'].apply(lambda x: np.nan if x < 90 else x)
10 loops, best of 3: 102 ms per loop

In [854]: %timeit sample['PR'].mask(sample['PR'] < 90, np.nan)
The slowest run took 4.28 times longer than the fastest. This could mean that an intermediate result is being cached.
100 loops, best of 3: 3.71 ms per loop
24
jezrael

条件(ここではx <90)が満たされた場合にどうするかを指示しているのに、条件が満たされていない場合に何をすべきかを指示していないため、ラムダ関数にelseを追加する必要があります。

sample['PR'] = sample['PR'].apply(lambda x: 'NaN' if x < 90 else x)