2017-03-13 6 views
3

import pandas as pd 
import numpy as np 
d = {'l': ['left', 'right', 'left', 'right', 'left', 'right'], 
    'r': ['right', 'left', 'right', 'left', 'right', 'left'], 
    'v': [-1, 1, -1, 1, -1, np.nan]} 
df = pd.DataFrame(d) 

通報グループ化データフレームは、私がskipna=Falseフラグによって与えられるようにグループ化された和はNaNになりたいnp.NaNの値を含む

pd.Series.sumpd.DataFrame.sumしかし、この加算グループ化されたパンダのデータフレーム内の行と戻りのNaN

In [235]: df.v.sum(skipna=False) 
Out[235]: nan 

しかし、この動作がされますpandas.DataFrame.groupbyオブジェクト

In [237]: df.groupby('l')['v'].sum()['right'] 
Out[237]: 2.0 

に反映されていないと

check_cols = ['v'] 
df['flag'] = df[check_cols].isnull().any(axis=1) 
df.groupby('l')['v', 'flag'].apply(np.sum).apply(
    lambda x: x if not x.flag else np.nan, 
    axis=1 
) 

が、これをすることによって、私はこの問題を回避することができますnp.sum方法直接

In [238]: df.groupby('l')['v'].apply(np.sum)['right'] 
Out[238]: 2.0 

回避策

を適用することにより、強制することはできません醜いです。より良い方法はありますか?

答えて

2

私はそれがパンダに固有のだと思います。回避策が使用できます

df.groupby('l')['v'].apply(array).apply(sum) 

良い機能を呼び出すために、

または

df.groupby('l')['v'].apply(pd.Series.sum,skipna=False) # for series, or 
df.groupby('l')['v'].apply(pd.DataFrame.sum,skipna=False) # for dataframes. 

をnumpyのやり方を模倣します。

+0

複数の列(つまり、DataFrame)に追加すると、メソッドが '.apply(pd.DataFrame.sum、skipna = False)に変更される –

0

それはあなたが望むものですか?

In [24]: df.groupby('l')['v'].agg(lambda x: np.nan if x.isnull().any() else x.sum()) 
Out[24]: 
l 
left -3.0 
right NaN 
Name: v, dtype: float64 

または

In [22]: df.groupby('l')['v'].agg(lambda x: x.sum() if x.notnull().all() else np.nan) 
Out[22]: 
l 
left -3.0 
right NaN 
Name: v, dtype: float64 
1

これは醜スケールで落ちるところ私はわからないんだけど、それは動作します:

>>> series_sum = pd.core.series.Series.sum 
>>> df.groupby('l')['v'].agg(series_sum, skipna=False) 
l 
left  -3 
right NaN 
Name: v, dtype: float64 

は、私はちょうどあなたがskipnaオプションをサポートする、df.v.sumを取ったときに使用しsum方法を掘っ:

>>> help(df.v.sum) 
Help on method sum in module pandas.core.generic: 

sum(axis=None, skipna=None, level=None, numeric_only=None, **kwargs) method 
of pandas.core.series.Series instance 
関連する問題