2016-11-20 8 views
2

私はname列とdepartment列のデータフレームを持っています。 name列には、異なるdepartment値を持つ反復がありますが、その他の列の値はすべて同じです。 フラット化これらの繰り返しを1行にして、異なる(ユニークな)部門値をリストに結合したいと思います。したがって、各グループの最初の行を取り出し、そのグループ内の一意のdepartment値のリストにdepartmentの値を変更します。結果として得られるデータフレームは全く同じ列を持ちますが、name列には繰り返しはなく、department列には少なくとも1つの要素のリストがあります。カスタムpandas groupby集計関数を使用してデータフレーム内の行を結合する方法

私はgroupbyを使用し、カスタム集計関数はagg()に渡されましたが、以下は完全に失敗します。私の考えは、私の集計関数が各グループをデータフレームとして取得し、各データフレームグループについてシリーズを返した場合、groupby.agg(flatten_departments)の出力はデータフレームになります。

def flatten_departments(name_group): 
    #I thought name_group would be a df of that group 

    #this group is length 1 so this name doesn't actually repeat so just return same row 
    if len(name_group) == 1: 
     return name_group.squeeze() #turn length-1 df into a series to return, don't worry that department is a string and not a list for now 
    else: 
     #treat name_group like a df and get the unique departments 
     departments = list(name_group['department'].unique()) 
     name_ser = name_group.iloc[0,:] #take first "row" of this group 
     name_ser['department'] = departments #replace department value with list of unique values from group 

     return name_ser 

my_df = my_df.groupby(['name']).agg(flatten_departments) 

これは、災害であり、name_groupは、DFが、そのインデックス元DFからインデックスであるシリーズではなく、名前がその列の値元DF価値のいくつかの他の列の名前であります。

私は

list_of_ser = [] 
for name, gp in my_df.groupby(['name']): 
    if len(gp) == 1: 
     list_of_ser.append(gp.squeeze()) 
    else: 
     new_ser = gp.iloc[0,:] 
     new_ser['department'] = list(gp['department'].unique()) 
     list_of_ser.append(new_ser) 

new_df = pd.DataFrame(list_of_ser, columns=my_df.columns) 

を次のように私はちょうどgroupbyオブジェクトをループのために行うことができることを知っているが、私はちょうどそれがaggのポイントだと思いました!

aggで目標を達成する方法や、forループが本当に正しい方法であるかについてのアイデア。 forループが正しい場合、aggのポイントは何ですか?

ありがとうございました!あなたが他のすべての列を保持する必要がある場合

答えて

1
df = pd.DataFrame(
    dict(
     name=list('ABCDEFGACEF'), 
     dept=list('xyxyzxyzyxz') 
    ) 
) 

df.groupby('name').dept.apply(list).reset_index() 

enter image description here


aggこの

df.groupby('name').dept.agg(dict(dept=lambda x: list(x))).reset_index() 

のように使用されている可能性が

df = pd.DataFrame(
    dict(
     name=list('ABCDEFGACEF'), 
     dept=list('xyxyzxyzyxz') 
    ) 
) 

g = df.groupby('name') 
pd.concat([g.dept.apply(list), g.first().drop('dept', 1)], axis=1).reset_index() 
+0

あなたの答えをありがとう、その1行の適用は完全に上司です。また、「コラム」のように辞書表記法を使って、あなたの 'agg'の例を理解しています。私がまだ混乱しているのは、パラメータが関数の場合に 'agg'をどう使いますか?' agg'ではその関数の "規則"は何ですか?なぜそれは他のランダムな列のシリーズを渡されているのですか? – ministry

+0

'.agg'の前に' .dept'を見てください。つまり、私はすでに 'agg'をシリーズに限定しています。これは、 'dict(dept = lambda)'が 'lambda'を使用し、' dept'カラムを呼び出すことを指定していることを意味します。 'dict'の' dept'を変更すると、別の列名があります。この場合は 'agg'を使用しません。私はちょうどあなたに例を挙げたかったので、何が起こっていたのかをよりよく知ることができました。 – piRSquared

+0

'apply'呼び出しから出てくるデータフレームには' name'と 'department'カラムしかありません。残りのカラムもどうやって元に戻すのですか? – ministry

関連する問題