2012-09-13 18 views
8

グループ化されたDataFrameの複数の列を組み合わせて新しいDataFrameを作成することがよくあります。適用()関数は、私はそれを行うことができますが、それは、私は不要なインデックスを作成する必要があります。余分なインデックスを追加せずにPandas groupby apply()を使用する方法

In [359]: df = pandas.DataFrame({'x': 3 * ['a'] + 2 * ['b'], 'y': np.random.normal(size=5), 'z': np.random.normal(size=5)}) 

In [360]: df 
Out[360]: 
    x   y   z 
0 a 0.201980 -0.470388 
1 a 0.190846 -2.089032 
2 a -1.131010 0.227859 
3 b -0.263865 -1.906575 
4 b -1.335956 -0.722087 

In [361]: df.groupby('x').apply(lambda x: pandas.DataFrame({'r': (x.y + x.z).sum()/x.z.sum(), 's': (x.y + x.z ** 2).sum()/x.z.sum()})) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
/home/emarkley/work/src/partner_analysis2/main.py in <module>() 
----> 1 df.groupby('x').apply(lambda x: pandas.DataFrame({'r': (x.y + x.z).sum()/x.z.sum(), 's': (x.y + x.z ** 2).sum()/x.z.sum()})) 

/usr/local/lib/python3.2/site-packages/pandas-0.8.2.dev-py3.2-linux-x86_64.egg/pandas/core/groupby.py in apply(self, func, *args, **kwargs) 
    267   applied : type depending on grouped object and function 
    268   """ 
--> 269   return self._python_apply_general(func, *args, **kwargs) 
    270 
    271  def aggregate(self, func, *args, **kwargs): 

/usr/local/lib/python3.2/site-packages/pandas-0.8.2.dev-py3.2-linux-x86_64.egg/pandas/core/groupby.py in _python_apply_general(self, func, *args, **kwargs) 
    417    group_axes = _get_axes(group) 
    418 
--> 419    res = func(group, *args, **kwargs) 
    420 
    421    if not _is_indexed_like(res, group_axes): 

/home/emarkley/work/src/partner_analysis2/main.py in <lambda>(x) 
----> 1 df.groupby('x').apply(lambda x: pandas.DataFrame({'r': (x.y + x.z).sum()/x.z.sum(), 's': (x.y + x.z ** 2).sum()/x.z.sum()})) 

/usr/local/lib/python3.2/site-packages/pandas-0.8.2.dev-py3.2-linux-x86_64.egg/pandas/core/frame.py in __init__(self, data, index, columns, dtype, copy) 
    371    mgr = self._init_mgr(data, index, columns, dtype=dtype, copy=copy) 
    372   elif isinstance(data, dict): 
--> 373    mgr = self._init_dict(data, index, columns, dtype=dtype) 
    374   elif isinstance(data, ma.MaskedArray): 
    375    mask = ma.getmaskarray(data) 

/usr/local/lib/python3.2/site-packages/pandas-0.8.2.dev-py3.2-linux-x86_64.egg/pandas/core/frame.py in _init_dict(self, data, index, columns, dtype) 
    454   # figure out the index, if necessary 
    455   if index is None: 
--> 456    index = extract_index(data) 
    457   else: 
    458    index = _ensure_index(index) 

/usr/local/lib/python3.2/site-packages/pandas-0.8.2.dev-py3.2-linux-x86_64.egg/pandas/core/frame.py in extract_index(data) 
    4719 
    4720   if not indexes and not raw_lengths: 
-> 4721    raise ValueError('If use all scalar values, must pass index') 
    4722 
    4723   if have_series or have_dicts: 

ValueError: If use all scalar values, must pass index 

In [362]: df.groupby('x').apply(lambda x: pandas.DataFrame({'r': (x.y + x.z).sum()/x.z.sum(), 's': (x.y + x.z ** 2).sum()/x.z.sum()}, index=[0])) 
Out[362]: 
      r   s 
x      
a 0 1.316605 -1.672293 
b 0 1.608606 -0.972593 

は、余分なインデックスなしで同じ結果を得るために(適用使用する方法)、または他のいくつかの機能がありますゼロの?

答えて

9

あなたがここにSeriesを使用する必要がありますので、あなたは、グループごとに集計rおよびs値を生産している:

In [26]: df.groupby('x').apply(lambda x: 
      Series({'r': (x.y + x.z).sum()/x.z.sum(), 
        's': (x.y + x.z ** 2).sum()/x.z.sum()})) 
Out[26]: 
      r   s 
x      
a -0.338590 -0.916635 
b 66.655533 102.566146 
+0

パーフェクト!どのように私がそれを逃したのか分からない。 – user2303

+0

ありがとう。私はシリーズを返すべきであることも知らず、DataFrameを返そうとしました。この情報(シリーズを返すべきである)は、公式文書に記載されていなければなりません。 – JustAC0der

関連する問題