2017-02-01 10 views
0

팬더 및 맞춤 그룹 집계에 관한 질문이있어 내 값을 계산하는 가장 효율적인 방법을 찾을 수 있습니다. 여기 내 코드입니다 :팬더 맞춤 그룹 집계

import pandas as pd 

listA = list('abcdefghijklmnopqrstuvwxyz') * 2 
listB = listA[::-1] 
listC = listA[::2] * 2 
listD = "Won" 
data1 = range(52) 
data2 = range(52,104) 
data3 = range(104,156) 

rawStructure = [('A', listA), 
       ('B', listB), 
       ('C', listC), 
       ('D', listD), 
       ('Data1', data1), 
       ('Data2', data2), 
       ('Data3', data3)] 
df = pd.DataFrame.from_items(rawStructure, orient='columns') 

df.loc[40:,"D"] = "Lost" 

def customfct(x,y,z): 
    print('x',x) 
    data = round(((x.sum() + y.sum())/z.sum()) * 100,2) 
    return data 

def f(row): 
    val1 = row.loc[(row['D'] == "Won"), 'Data1'].sum() 
    val2 = row.loc[(row['D'] == "Won"), 'Data2'].sum() 
    val3 = row.loc[(row['D'] == "Won"), 'Data3'].sum() 
    val4 = customfct(row.loc[(row['D'] == "Won"), 'Data1'], row.loc[(row['D'] == "Won"), 'Data2'], row.loc[(row['D'] == "Won"), 'Data3']) 
    return val1, val2, val3, val4 

groupByCriteria = "C" 
agg = df[:].groupby(by=groupByCriteria).apply(f) 
print(agg) 

내가 그룹을 다른 열을 사용하는 기능 "customfct"(같은 사용자 정의 계산을 적용 할 수있는보다 효율적인 방법이 있는지 알고 싶습니다 (데이터 1, 데이터 2, DATA3)). 첫 번째 접근 방식은 여기에서 볼 수있는 것과 같았습니다 : http://www.shanelynn.ie/summarising-aggregation-and-grouping-data-in-python-pandas/하지만 한 열 (예 : lambda x : max (x) - min (x))에 제약이없는 수식을 만드는 것은 실행 불가능한 것으로 보입니다. 또한 팬더 시리즈 (튜플 포함) 대신 팬더 데이터 프레임을 어떻게 반환합니까? 미리 감사드립니다!

내 현재 출력

(정확하지만 나는 더 효율적인 방법이 추측) :

Pandas output

+0

구체적인 첫 번째 질문은 무엇입니까? 아마도 실제 데이터, 현재 결과, 원하는 결과가 도움이 될 것입니다. – Parfait

+0

원본 게시물에 몇 가지 변경 사항을 적용 했습니까? – Sebastian

답변

0

새를 생성 한 후 한 groupby() 호출에 모든 데이터 열을 집계 고려하고 val4에 대한 열 그런 다음 집계를 원래 데이터 프레임으로 병합합니다. 비교 타이밍


# EQUIVALENT EXAMPLE DATA 
listA = list('abcdefghijklmnopqrstuvwxyz') * 2 
df = pd.DataFrame({'A': listA, 'B': listA[::-1], 'C': listA[::2] * 2, 
        'D': ["Won" for i in range(40)] + ["Lost" for i in range(40,52)], 
        'Data1': range(52), 'Data2': range(52,104), 'Data3': range(104,156)}) 

# ADJUSTED METHOD 
groupByCriteria = "C" 
grp = df[df['D']=="Won"].groupby(by=groupByCriteria).sum().reset_index()\ 
           .rename(columns={'Data1':'val1','Data2':'val2','Data3':'val3'}) 
grp['val4'] = round(((grp['val1'] + grp['val2'])/grp['val3']) * 100,2) 

agg = df.merge(grp, on='C').sort_values('Data1').reset_index(drop=True) 
는 조정 코드 현저히 빠르다. 노트 : 메소드는 일련이 아닌 데이터 프레임을 반환하도록 조정되었습니다.

def origfct(): 
    def customfct(x,y,z): 
     #print('x',x) 
     data = round(((x.sum() + y.sum())/z.sum()) * 100,2) 
     return data 

    def f(row): 
     row['val1'] = row.loc[(row['D'] == "Won"), 'Data1'].sum() 
     row['val2'] = row.loc[(row['D'] == "Won"), 'Data2'].sum() 
     row['val3'] = row.loc[(row['D'] == "Won"), 'Data3'].sum() 
     row['val4'] = customfct(row.loc[(row['D'] == "Won"), 'Data1'], 
           row.loc[(row['D'] == "Won"), 'Data2'], 
           row.loc[(row['D'] == "Won"), 'Data3']) 
     return row 

    groupByCriteria = "C" 
    agg = df[:].groupby(by=groupByCriteria).apply(f) 
    return agg 

def newsetup(): 
    groupByCriteria = "C" 
    grp = df[df['D']=="Won"].groupby(by=groupByCriteria).sum().reset_index()\ 
          .rename(columns={'Data1':'val1','Data2':'val2','Data3':'val3'}) 
    grp['val4'] = round(((grp['val1'] + grp['val2'])/grp['val3']) * 100,2) 

    agg = df.merge(grp, on='C').sort_values('Data1').reset_index(drop=True) 
    return agg 


python -mtimeit -n'100' -s'import pyscript as test' 'test.origfct()' 
# 100 loops, best of 3: 198 msec per loop 

python -mtimeit -n'100' -s'import pyscript as test' 'test.newsetup()' 
# 100 loops, best of 3: 16 msec per loop 
+0

그것이 바로 내가 찾고있는 것입니다. 신속하게 계산을하는 아주 좋은 접근법. 나는 재결합하는 테이블을 생각하지 않았다. 고마워요! – Sebastian