2012-07-10 6 views
1

나는 종 조사 횟수가 dataframe이며 여러 기준에 따라 행을 집계해야합니다. 주요 문제는 계절 샘플을 다른 연도에 일치시켜야한다는 것입니다. 예를 들어 2005 년 봄 샘플은 2006 년 가을 샘플과 일치 할 것이며 샘플 샘플 방법과 복제가 일치합니다.팬더 데이터 프레임을 일치하지 않는 기준으로 집계하는 더 좋은 방법

# create the factors and dataframe 
a = repeat('AAA',4) 
b = repeat('BBB',2) 
y1 = np.array([2005, 2006]) 
y2 = np.array([2005, 2007]) 
r = np.array([1, 1, 2, 2, 1 , 1]) 
d = {'site' : hstack((a,b,a,b,a,b,a,b)), 
    'year' : hstack((y1, y1, y1, y2, y2, y2, y1, y1, y1, y2, y2, y2)), 
    'season' : hstack((repeat('AUTUMN', 6), repeat('SPRING', 6), repeat('AUTUMN', 6), repeat('SPRING', 6))), 
    'method' : hstack((repeat('EDGE', 12), repeat('RIFFLE', 12))), 
    'replicate' : hstack((r, r, r, r))} 
df = DataFrame(d) 

# now add some species 
df['sp1'] = 1 
df['sp2'] = 2 
df['sp3'] = 3 

dataframe의 각 행 분량의 샘플이다 : 여기서, 데이터의 간단한 예이다. 현재 'ID'열을 새로 만들고 있는데 'SPRING'샘플을 반복하여 일치하는 가을 샘플을 검색하고 'id'를 그룹화하기 전에 두 샘플의 'id'를 업데이트합니다. 예를 들면 다음과 같습니다.

df['id'] = 'na' # new column for combined season id 
grouped = df.groupby('season') # split table by season 

for name, group in grouped: 
    if name == 'AUTUMN': 
     aut = group #autumn lookup list 
    if name == 'SPRING': 
     # for each spring sample 
     for row_index, row in group.iterrows(): 
      # check for matching autumn sample 
      n = aut[ 
       (aut['site'] == row['site']) & 
       (aut['year'] == row['year'] + 1) & 
       (aut['method'] == row['method']) & 
       (aut['replicate'] == row['replicate'])].index 
      if n: 
       # create new combined season id 
       new_id = row['site'] + \ 
         str(row['year'])[-2:] + \ 
         str(row['year'] + 1)[-2:] + \ 
         row['method'][:1] + \ 
         str(row['replicate']) 
       # update id spring sample with matching autumn 
       df.id.ix[row_index] = new_id 
       # get matching autumn table index 
       df.id.ix[n] = new_id 
df = df[df['id'] != 'na'] 
combined = df.groupby(['method', 'id', 'site']).sum() 
combined = combined.drop(['year', 'replicate'], axis=1) 

이 방법은 상당히 잘 작동하지만 약간은 어색하고 다재다능하지 않습니다. 이런 방식으로 데이터를 모으는 벡터화 된 방법이 있습니까? 게시물의 길이를 유감스럽게 생각하고 무엇이 불분명한지 알려주세요. 사전에

덕분에

답변

1

는 편집 :

코드

수정이 방법에 대해 :

In [20]: grouped.sum()[grouped.size() > 1] 
Out[20]: 
          sp1 sp2 sp3 
method replicate site year    
EDGE 1   AAA 2006 2 4 6 
       BBB 2006 2 4 6 
     2   AAA 2006 2 4 6 
RIFFLE 1   AAA 2006 2 4 6 
       BBB 2006 2 4 6 
     2   AAA 2006 2 4 6 
:

adjyear = np.where(df.season == 'SPRING', df.year + 1, df.year) 
adjyear.name = 'year' 

grouped = df.groupby(['method', 'replicate', 'site', adjyear]) 
grouped = grouped['sp1', 'sp2', 'sp3']  

grouped.sum()[grouped.size() > 1] 

이 나에게 준다

관련 문제