複数列 - python groupby




Pandas Groupby Agg関数が減少しない (2)

これはDataFrameの誤った機能です。 アグリゲータが最初のグループのリストを返すと、あなたが言及したエラーで失敗します。 最初のグループの非リスト(非シリーズ)を返す場合、正常に動作します。 壊れたコードはgroupby.pyにあります:

def _aggregate_series_pure_python(self, obj, func):

    group_index, _, ngroups = self.group_info

    counts = np.zeros(ngroups, dtype=int)
    result = None

    splitter = get_splitter(obj, group_index, ngroups, axis=self.axis)

    for label, group in splitter:
        res = func(group)
        if result is None:
            if (isinstance(res, (Series, Index, np.ndarray)) or
                    isinstance(res, list)):
                raise ValueError('Function does not reduce')
            result = np.empty(ngroups, dtype='O')

        counts[label] = group.shape[0]
        result[label] = res

if result is Noneisinstance(res, list 。オプションは次のとおりです。

  1. groupby()。agg()を偽造しているため、最初のグループのリストが表示されません。

  2. 上記のようなコードを使用して、間違ったテストをせずに、自分で集約を行います。

私は今私の仕事で長年使ってきた集計関数を使用しています。 アイデアは、関数に渡された系列が長さ1の場合(つまり、グループには1つの観測のみがある場合)、その観測値が返されるということです。 渡された系列の長さが1より大きい場合、観測値はリストに戻されます。

これはいくつかの人にとっては奇妙に思えるかもしれませんが、これはX、Yの問題ではありません。私はこの質問には関係のない、これをしたいという理由があります。

これは私が使用している関数です:

def MakeList(x):
    """ This function is used to aggregate data that needs to be kept distinc within multi day 
        observations for later use and transformation. It makes a list of the data and if the list is of length 1
        then there is only one line/day observation in that group so the single element of the list is returned. 
        If the list is longer than one then there are multiple line/day observations and the list itself is 
        returned."""
    L = x.tolist()
    if len(L) > 1:
        return L
    else:
        return L[0]

今私は現在作業中のデータセットで、何らかの理由で、関数が減少しないことを示すValueErrorを取得します。 ここにいくつかのテストデータと私が使っている残りのステップがあります:

import pandas as pd
DF = pd.DataFrame({'date': ['2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02'],
                    'line_code':   ['401101',
                                    '401101',
                                    '401102',
                                    '401103',
                                    '401104',
                                    '401105',
                                    '401105',
                                    '401106',
                                    '401106',
                                    '401107'],
                    's.m.v.': [ 7.760,
                                25.564,
                                25.564,
                                9.550,
                                4.870,
                                7.760,
                                25.564,
                                5.282,
                                25.564,
                                5.282]})
DFGrouped = DF.groupby(['date', 'line_code'], as_index = False)
DF_Agg = DFGrouped.agg({'s.m.v.' : MakeList})

これをデバッグしようとすると、print文をprint Lprint x.index効果にprint x.index 、出力は次のようになりました:

[7.7599999999999998, 25.564]
Int64Index([0, 1], dtype='int64')
[7.7599999999999998, 25.564]
Int64Index([0, 1], dtype='int64')

何らかの理由で、 aggがSeriesを関数に2回渡しているようです。 これは私が知る限り、まったく正常ではなく、おそらく私の機能が低下していない理由です。

たとえば、次のような関数を書くとします。

def test_func(x):
    print x.index
    return x.iloc[0]

これは問題なく実行され、printステートメントは次のとおりです。

DF_Agg = DFGrouped.agg({'s.m.v.' : test_func})

Int64Index([0, 1], dtype='int64')
Int64Index([2], dtype='int64')
Int64Index([3], dtype='int64')
Int64Index([4], dtype='int64')
Int64Index([5, 6], dtype='int64')
Int64Index([7, 8], dtype='int64')
Int64Index([9], dtype='int64')

これは、各グループがSeriesとして関数に1回だけ渡されていることを示します。

なぜこれが失敗しているのか誰にでも理解できますか? 私はこの機能を多くのデータセットで成功させるために使用しています....

ありがとう


私は本当に理由を説明することはできませんが、 pandas.DataFrame私の経験listから、 pandas.DataFrameしません。

私は通常、代わりにtupleを使用します。 それは動作します:

def MakeList(x):
    T = tuple(x)
    if len(T) > 1:
        return T
    else:
        return T[0]

DF_Agg = DFGrouped.agg({'s.m.v.' : MakeList})

     date line_code           s.m.v.
0  2013-04-02    401101   (7.76, 25.564)
1  2013-04-02    401102           25.564
2  2013-04-02    401103             9.55
3  2013-04-02    401104             4.87
4  2013-04-02    401105   (7.76, 25.564)
5  2013-04-02    401106  (5.282, 25.564)
6  2013-04-02    401107            5.282




pandas