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

データフレームの各行は単一のサンプルです。現在、新しいマージされた「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)

この方法は非常にうまく機能しますが、少し扱いに​​くく、汎用性がまったくないと思います。この方法でデータを集約するベクトル化された方法はありますか? 文章が長くなってしまい申し訳ありませんが、不明な点がありましたらお知らせください。

前もって感謝します

4

1 に答える 1

1

編集:修正されたコード

これはどう:

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]

これは私に与えます:

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
于 2012-07-11T15:04:44.787 に答える