2017-01-18 3 views
2

이것은 이전 문제의 확장입니다. python pandas rolling function with two arguments.그룹화 된 DataFrame에서 두 개의 인수가있는 Python pandas 롤링 기능

그룹별로 어떻게 수행합니까? 아래의 'C'열을 그룹화에 사용한다고 가정 해 보겠습니다. I가 고민하고

: 일종의 'A'

  • 각 그룹 withing에 의해, 각 그룹 내에서 열 'C'
  • 에 의해

    1. 그룹은 롤링 기능이 kendalltau처럼, 두 개의 인수를 복용 적용 인수 'A'와 'B'.

    예상되는 결과는 아래와 같은 DataFrame 될 것이다 :

    expected result

    내가 위의 링크에 설명 된대로 '인덱스를 통과'해결 방법을 시도하지만,이의 복잡 한 경우 :-(내 능력을 넘어이다. 이것은 모든 내가 C을 수정하지 멀리 단순화를 위해 내가 무작위로 생성 된 데이터를 사용, 그래서 내가 작업하고있는 무슨에서.

    rand = np.random.RandomState(1) 
    dff = pd.DataFrame({'A' : np.arange(20), 
            'B' : rand.randint(100, 120, 20), 
            'C' : rand.randint(0, 2, 20)}) 
    
    def my_tau_indx(indx): 
        x = dff.iloc[indx, 0] 
        y = dff.iloc[indx, 1] 
        tau = sp.stats.mstats.kendalltau(x, y)[0] 
        return tau 
    
    dff['tau'] = dff.sort_values(['C', 'A']).groupby('C').rolling(window = 5).apply(my_tau_indx, args = ([dff.index.values])) 
    

    장난감 예이다 또 다른 버그를 reates ...

    위의 문제는 Nickil Maveli에 의해 해결되었으며 numpy 1.11.0, pandas 0.18.1, scipy 0.17.1 및 conda 4.1.4와 함께 작동합니다. 경고를 생성하지만 작동합니다. 내 다른 시스템에서


    의 최신 & 큰 NumPy와 1.12.0, 팬더 0.19.2, 0.18.1 scipy, CONDA 버전 3.10.0 및 BLAS/LAPACK는 - 그것은 작동하지 않습니다와 나는 아래의 역 추적을 얻을 . 이것은 제 1의 기계를 업 그레 이드 한 이래로 관련이있는 것 같습니다. 또한 작동을 멈췄습니다 ... 과학의 이름으로 ... ;-)

    Nickil이 제안했듯이 이것은 numpy 1.11과 1.12 사이의 비 호환성 때문이었습니다. numpy 다운 그레이드가 도움이되었습니다. Windows에서 BLAS/LAPACK을 사용했기 때문에 http://www.lfd.uci.edu/~gohlke/pythonlibs/에서 1.11.3 + mkl을 설치했습니다.

    Traceback (most recent call last): 
    
    File "<ipython-input-4-bbca2c0e986b>", line 16, in <module> 
    t = grp.apply(func) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\groupby.py", line 651, in apply 
    return self._python_apply_general(f) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\groupby.py", line 655, in _python_apply_general 
    self.axis) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\groupby.py", line 1527, in apply 
    res = f(group) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\groupby.py", line 647, in f 
    return func(g, *args, **kwargs) 
    
    File "<ipython-input-4-bbca2c0e986b>", line 15, in <lambda> 
    func = lambda x: pd.Series(pd.rolling_apply(np.arange(len(x)), 5, my_tau_indx), x.index) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\stats\moments.py", line 584, in rolling_apply 
    kwargs=kwargs) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\stats\moments.py", line 240, in ensure_compat 
    result = getattr(r, name)(*args, **kwds) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\window.py", line 863, in apply 
    return super(Rolling, self).apply(func, args=args, kwargs=kwargs) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\window.py", line 621, in apply 
    center=False) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\window.py", line 560, in _apply 
    result = calc(values) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\window.py", line 555, in calc 
    return func(x, window, min_periods=self.min_periods) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\window.py", line 618, in f 
    kwargs) 
    
    File "pandas\algos.pyx", line 1831, in pandas.algos.roll_generic (pandas\algos.c:51768) 
    
    File "<ipython-input-4-bbca2c0e986b>", line 8, in my_tau_indx 
    x = dff.iloc[indx, 0] 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\indexing.py", line 1294, in __getitem__ 
    return self._getitem_tuple(key) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\indexing.py", line 1560, in _getitem_tuple 
    retval = getattr(retval, self.name)._getitem_axis(key, axis=axis) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\indexing.py", line 1614, in _getitem_axis 
    return self._get_loc(key, axis=axis) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\indexing.py", line 96, in _get_loc 
    return self.obj._ixs(key, axis=axis) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\core\frame.py", line 1908, in _ixs 
    label = self.index[i] 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\indexes\range.py", line 510, in __getitem__ 
    return super_getitem(key) 
    
    File "C:\Apps\Anaconda\v2_1_0_x64\envs\python35\lib\site-packages\pandas\indexes\base.py", line 1275, in __getitem__ 
    result = getitem(key) 
    
    IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices 
    

    최종 검사 : 모든 그룹을 통해 반복하고 모든 같은 그룹에 pd.rolling_apply을 사용하는 것입니다 달성하기

    enter image description here

  • +0

    예상되는 출력은 무엇입니까? –

    +0

    @Andrew L - 감사합니다. 나는 이것이 유추 될 수 있다고 잘못 추측했습니다.나는 그것이 지금 더 분명하기를 바란다. – rpl

    답변

    1

    한 가지 방법.

    import scipy.stats as ss 
    
    def my_tau_indx(indx): 
        x = dff.iloc[indx, 0] 
        y = dff.iloc[indx, 1] 
        tau = ss.mstats.kendalltau(x, y)[0] 
        return tau 
    
    grp = dff.sort_values(['A', 'C']).groupby('C', group_keys=False) 
    func = lambda x: pd.Series(pd.rolling_apply(np.arange(len(x)), 5, my_tau_indx), x.index) 
    t = grp.apply(func) 
    dff.reindex(t.index).assign(tau=t) 
    

    enter image description here


    편집 :

    def my_tau_indx(indx): 
        x = dff.ix[indx, 0] 
        y = dff.ix[indx, 1] 
        tau = ss.mstats.kendalltau(x, y)[0] 
        return tau 
    
    grp = dff.sort_values(['A', 'C']).groupby('C', group_keys=False) 
    t = grp.rolling(5).apply(my_tau_indx).get('A') 
    
    grp.head(dff.shape[0]).reindex(t.index).assign(tau=t) 
    

    enter image description here

    +1

    솔루션을 게시 해 주셔서 감사합니다. 'pd.rolling_apply'는 deprecated 될 것이기 때문에'rolling '와 같은 것을 달성 할 수있는 방법이 있는지 궁금합니다. 또한, (이것은 더 많은 호기심입니다.) 글로벌 변수를 수정하는 함수에 의존하지 않는 솔루션이 마음에 떠오 릅니까? – rpl

    +1

    'DF.rolling(). apply()'는 커스텀 함수에서 현재 형태로 스칼라 값을 반환 할 수 있다고 생각하지 않습니다. 대안은 슬라이딩 윈도우 목록 이해력을 사용하여이를 재 설계 한 다음 너무 많은 노력처럼 보이는 여러 가지 계산을 연쇄 적으로 연결하는 것입니다. 이제는 pd.rolling_apply()를 계속 사용하고 앞으로 개선 될 버전이 나올 때까지 기다리거나 [**이 문제를 해결하는 github에 문제 게시 **] (https://github.com)하는 것이 좋습니다./pandas-dev/pandas/issues) –

    +0

    디버깅하기 쉽도록 전체 추적으로 질문을 편집 할 수 있습니까? 이전에 제대로 작동 했습니까? –

    관련 문제