2016-04-06 7 views
5

私はidでグループ化されたデータフレームを持っています。多くのグループがあり、各グループには可変数の行があります。すべてのグループの最初の3行には興味深いデータは含まれていません。私は各グループの最初の3つの行を次のようにして1行を形成するように "崩壊"したいと思います:パンダ:集計によって各グループの最初のn行を折りたたみます

「id」は新しい '折りたたみ'の行で同じままです。
「grp_idx」が変更されます「0」の最初の3行の凝集は最初の3行の和になり
COL_1が発生した場合
col_2は、最初の3行
「フラグ」の和であろう最初の3行で値がすべて0の場合、「折りたたまれた」行の値は0になります。最初の3行のいずれかが1の場合、 'flag'は1になります。ここ

を(フラグのみ、全てのグループのために一列に設定されているので、簡単な和が、このロジックに十分であろう)データフレームがどのように見えるかの例である:処理後

import pandas as pd 
import numpy as np 
df = pd.DataFrame.from_items([ 
    ('id', [283,283,283,283,283,283,283,756,756,756]), 
    ('type', ['A','A','A','A','A','A','A','X','X','X']), 
    ('grp_idx', [1,2,3,4,5,6,7,1,2,3]), 
    ('col_1', [2,4,6,8,10,12,14,5,10,15]), 
    ('col_2', [3,6,9,12,15,18,21,1,2,3]), 
    ('flag', [0,0,0,0,0,0,1,0,0,1]), 
    ]); 
print(df) 

    id type grp_idx col_1 col_2 flag 
0 283 A  1  2  3  0 
1 283 A  2  4  6  0 
2 283 A  3  6  9  0 
3 283 A  4  8  12  0 
4 283 A  5  10  15  0 
5 283 A  6  12  18  0 
6 283 A  7  14  21  1 
7 756 X  1  5  1  0 
8 756 X  2  10  2  0 
9 756 X  3  15  3  1 

、私が期待しますデータフレームは次のようになります:

私はどのように進むのかは分かりません。私は。

df.groupby( 'ID')で遊ぶためにヘッド(3).SUM()

をしようとしていたが、これは私が必要なものをやっていません。助け、提案、コードスニペットは本当に感謝しています。

答えて

2

あなたはgrp_idxを設定することにより開始することができます

df.groupby(["id", "type", "grp_idx"]).sum().reset_index() 

    id type grp_idx col_1 col_2 flag 
0 283 A  0  12  18  0 
1 283 A  4  8  12  0 
2 283 A  5  10  15  0 
3 283 A  6  12  18  0 
4 283 A  7  14  21  1 
5 756 X  0  30  6  1 

私はあなたがdidnのようなタイプは、同じIDの異なることができないと仮定その列の条件を指定しないでください。私はdfがidでソートされているとも仮定しました。そうでない場合は、最初にgrp_idxをソートして正しいものにすることができます。

+0

恐ろしい!私はこれを私自身で決して解明したことはありません。お手伝いをしてくれてありがとう。 – Learner

+0

ようこそ。素晴らしい運動でした。 – ayhan

2

私はあなたがgroupby()を呼び出した後

df.groupby('id').head(3).sum() 

で遊んしようとしていた、あなたが望む方法で結合するためにaggregate()する必要があります。このような何かを試してみてください:

# function to sum the first 3 rows 
def head_sum(x): 
    return x.head(3).sum() 

# function to get max of first 3 rows 
def head_max(x): 
    return x.head(3).max() 

# We can use a dictionary in `aggregate()` to call a 
# specific function for each column in the groupby 
column_funcs = {'col_1': head_sum, 
       'col_2': head_sum, 
       'flag': head_max, 
       'id': max, # all the vals should be the same 
       'type': max} # are the 'id' and 'type' always matched? 
collapsed = df.groupby('id').aggregate(column_funcs) 
collapsed['grp_idx'] = 0 

new_df = pd.concat([df, collapsed]) 

は、スプリット適用-組み合わせるアプローチに関するより多くの情報のためhereを参照してください。 id

df["grp_idx"] = np.where(df.groupby("id").cumcount()<3, 0, df["grp_idx"]) 

grp_idxしたいグループを作成します:

+0

ありがとうZachary!あなたが概説したテクニックは本当に素晴らしいです。私の貧弱な知識に何か追加します。あなたの提案は確かに必要なものを達成するために働くことができます。最初の3行を削除するだけです。あなたの知識を共有してくれてありがとう。 – Learner

関連する問題