2016-05-05 3 views
0

2つの列を分割しようとしていますが、データにnull値があることがわかります。このデータフレームを想像:パンダラムダ関数のヌル値を適用する

df = pd.DataFrame(['fruit: apple','vegetable: asparagus',None, 'fruit: pear'], columns = ['text']) 

df 

        text 
0   fruit: apple 
1 vegetable: asparagus 
2     None 
3   fruit: pear 

私はそうのような複数の列にこれを分割したい:私は代わりに、次のDFを持っている場合は、しかし、

df['cat'] = df['text'].apply(lambda x: 'unknown' if x == None else x.split(': ')[0]) 
df['value'] = df['text'].apply(lambda x: 'unknown' if x == None else x.split(': ')[1]) 

print df 

        text  cat  value 
0   fruit: apple  fruit  apple 
1 vegetable: asparagus vegetable asparagus 
2     None unknown unknown 
3   fruit: pear  fruit  pear 

df = pd.DataFrame(['fruit: apple','vegetable: asparagus',np.nan, 'fruit: pear'], columns = ['text']) 

分割結果を次のエラー:

df['cat'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[0]) 

--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-159-8e5bca809635> in <module>() 
     1 df = pd.DataFrame(['fruit: apple','vegetable: asparagus',np.nan, 'fruit: pear'], columns = ['text']) 
     2 #df.columns = ['col_name'] 
----> 3 df['cat'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[0]) 
     4 df['value'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[1]) 

C:\Python27\lib\site-packages\pandas\core\series.pyc in apply(self, func, convert_dtype, args, **kwds) 
    2158    values = lib.map_infer(values, lib.Timestamp) 
    2159 
-> 2160   mapped = lib.map_infer(values, f, convert=convert_dtype) 
    2161   if len(mapped) and isinstance(mapped[0], Series): 
    2162    from pandas.core.frame import DataFrame 

pandas\src\inference.pyx in pandas.lib.map_infer (pandas\lib.c:62187)() 

<ipython-input-159-8e5bca809635> in <lambda>(x) 
     1 df = pd.DataFrame(['fruit: apple','vegetable: asparagus',np.nan, 'fruit: pear'], columns = ['text']) 
     2 #df.columns = ['col_name'] 
----> 3 df['cat'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[0]) 
     4 df['value'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[1]) 

AttributeError: 'float' object has no attribute 'split' 

NaN値で同じ分割を行うにはどうすればよいですか? 通常、ヌル値を無視する分割関数を適用する方が良い方法はありますか?

私は次のように持っていた代わりにあれば、これは文字列の例ではありませんでした想像:私はSeries.applyように感じる

df = pd.DataFrame([2,4,6,8,10,np.nan,12], columns = ['numerics']) 
df['numerics'].apply(lambda x: np.nan if pd.isnull(x) else x/2.0) 

はほとんどそれがヌル行をスキップするように指示する引数とちょうど出力としてそれらを取る必要がありますnulls。私はより良い発見していない手動でヌルを避けることなく、シリーズへの変換を行う方法。あなたはSeries.str.extract方法使用できるカスタム関数と

+0

はDF [ '猫']のdf [ 'テキストを'] = 'を試してみてください適用(ラムダX:。pd.isnull場合は '不明'(x)は、他のx.splitを( ':')[0 ]) ' – EdChum

答えて

5

代わりのapply:カスタム関数と

import numpy as np 
import pandas as pd 
# df = pd.DataFrame(['fruit: apple','vegetable: asparagus',None, 'fruit: pear'], 
#     columns = ['text']) 
df = pd.DataFrame(['fruit: apple','vegetable: asparagus',np.nan, 'fruit: pear'], 
        columns = ['text']) 
df[['cat', 'value']] = df['text'].str.extract(r'([^:]+):?(.*)', expand=True).fillna('unknown') 
print(df) 

利回り

    text  cat  value 
0   fruit: apple  fruit  apple 
1 vegetable: asparagus vegetable asparagus 
2     NaN unknown  unknown 
3   fruit: pear  fruit  pear 

applyは、一般的に使用する同等のコードよりも遅くなりますSeries.str.extractのようなベクトル化された方法の使用。フードの下では、apply(ベクトル化機能を持たない)は基本的にPython for-loopでカスタム関数を呼び出します。編集した問題に関しては


:あなたは

df = pd.DataFrame([2,4,6,8,10,np.nan,12], columns = ['numerics']) 

を持っている場合は、

In [207]: df['numerics']/2 
Out[207]: 
0 1.0 
1 2.0 
2 3.0 
3 4.0 
4 5.0 
5 NaN 
6 6.0 
Name: numerics, dtype: float64 

の代わりに、再び

df['numerics'].apply(lambda x: np.nan if pd.isnull(x) else x/2.0) 

使用は、ベクトル化算術は、カスタムでapplyを打ちます機能:

In [210]: df = pd.concat([df]*100, ignore_index=True) 

In [211]: %timeit df['numerics']/2 
10000 loops, best of 3: 93.8 µs per loop 

In [212]: %timeit df['numerics'].apply(lambda x: np.nan if pd.isnull(x) else x/2.0) 
1000 loops, best of 3: 836 µs per loop 
+0

あなたがNoneをnp.nanに置き換えた場合、爆弾... – flyingmeatball

+0

あなたはどのバージョンのパンダを使用していますか?バージョン0.18.0で動作します。 – unutbu

+0

17.0ですが、これは短所を反映する質問です。 – flyingmeatball

関連する問題