2016-03-15 4 views
5

に列を追加するために適用します。私はレベル1でグループ化し、新しい列を生成する関数を適用したい。私は、この計算されたカラムは、各グループに追加したいので、私のデータフレームは、グループごとに新しい列を持っています。GROUPBYを使用し、私は列として、多指数を有するデータフレームを有する各グループ

私は私が何をしたいレプリケートするために少しダミースクリプト機能を作りました。次のように

import pandas as pd 
import numpy as np 

columns = [('A','julian'),('A','geoffrey'), 
     ('B','julian'),('B','geoffrey'), 
     ('C','julian'),('C','geoffrey')] 

columns = pd.MultiIndex.from_tuples(columns) 

dataframe = pd.DataFrame(data=np.random.rand(10,6),columns=columns) 

def addColumn(inputDF): 
    group = inputDF.columns[0][1] 
    inputDF['sum', group] = inputDF.sum(axis=1) 
    return inputDF 

newColumnsDataframe = dataframe.groupby(level=1, axis=1).apply(addColumn) 

元データフレームが見えます:

 A     B     C   
    julian geoffrey julian geoffrey julian geoffrey 
0 0.204082 0.073676 0.795725 0.279702 0.258185 0.258112 
1 0.263235 0.096733 0.507324 0.541198 0.525919 0.757652 
2 0.196243 0.028613 0.653408 0.364365 0.174911 0.924733 
3 0.528785 0.831569 0.654160 0.738029 0.940831 0.294473 
4 0.853517 0.263250 0.803087 0.855270 0.701937 0.264698 
5 0.239797 0.069519 0.943544 0.374411 0.189361 0.846647 
6 0.980734 0.290414 0.850097 0.873785 0.903645 0.118713 
7 0.591942 0.088387 0.566298 0.062140 0.568482 0.872064 
8 0.818167 0.061483 0.282050 0.008404 0.449198 0.658370 
9 0.217424 0.427602 0.471933 0.171458 0.390549 0.234426 

次のように結果のデータフレームは、(私が別途加算データフレームを構築し、この結果を達成するために2つのデータフレームを連結)になります。

 A   B   C  sum   A   B   C \ 
    geoffrey geoffrey geoffrey geoffrey julian julian julian 
0 0.073676 0.279702 0.258112 0.611491 0.204082 0.795725 0.258185 
1 0.096733 0.541198 0.757652 1.395584 0.263235 0.507324 0.525919 
2 0.028613 0.364365 0.924733 1.317710 0.196243 0.653408 0.174911 
3 0.831569 0.738029 0.294473 1.864071 0.528785 0.654160 0.940831 
4 0.263250 0.855270 0.264698 1.383219 0.853517 0.803087 0.701937 
5 0.069519 0.374411 0.846647 1.290578 0.239797 0.943544 0.189361 
6 0.290414 0.873785 0.118713 1.282912 0.980734 0.850097 0.903645 
7 0.088387 0.062140 0.872064 1.022590 0.591942 0.566298 0.568482 
8 0.061483 0.008404 0.658370 0.728257 0.818167 0.282050 0.449198 
9 0.427602 0.171458 0.234426 0.833486 0.217424 0.471933 0.390549 

    sum 
    julian 
0 1.257992 
1 1.296478 
2 1.024561 
3 2.123776 
4 2.358542 
5 1.372703 
6 2.734476 
7 1.726721 
8 1.549415 
9 1.079906 

上記のスクリプトでのアプローチは、私には理にかなっているものに基づいており、どのような他の人はこの種のものをやって、オンラインで書かれています。しかし、newColumnsDataframeは依然としてわずか6列を有していない8(一つがそれぞれの名前のために添加)。

level = 0(A、B、またはC)でグループ化してtransformを使用すると、newColumnsDataframeには9つの列と1つの合計列が追加されています各グループごとに以下のコードを参照してください:

import pandas as pd 
import numpy as np 

columns = [('A','julian'),('A','geoffrey'), 
     ('B','julian'),('B','geoffrey'), 
     ('C','julian'),('C','geoffrey')] 

columns = pd.MultiIndex.from_tuples(columns) 

dataframe = pd.DataFrame(data=np.random.rand(10,6),columns=columns) 

def addColumn(inputDF): 
    group = inputDF.columns[0][1] 
    inputDF[group, 'sum'] = inputDF.sum(axis=1) 
    return inputDF 

newColumnsDataframe = dataframe.groupby(level=0, axis=1).transform(addColumn) 

それは一方で、全体データフレームとしてグループで運営適用するには、常にグループ内の各列に取り組ん変換私の理解でした。これは矛盾しているようです。 私も、私はレベル= 1でグループおよび適用の代わりにトランスフォームを使用するときに、気づいた、それは次のようなエラーがスローされます。

ValueError: Length mismatch: Expected axis has 10 elements, new values have 6 elements 

私は何が起こっているかについて非常に混乱しています。誰もがレベル= 0でtransformとgroupを使うとき、なぜこれがうまくいくのか知っていますか?なぜ私はレベル= 1で同じグループを行うときにエラーがあります。そして、なぜEITHERレベルでグループ化関数を適用することは、私の最後のデータフレームに列を追加しないのですか?前もって感謝します!

(PS:これは、実際のデータフレームまたは関数Iが列を追加するために使用しています、だけで簡単にイラストではありません):

(df.join(pd.concat({'sum': df.groupby(level=1, axis=1).sum()}, axis=1)) 
    .sortlevel(level=1, axis=1)) 

が生成する厄介なの

+1

希望の出力を追加できますか? – roadrunner66

+0

それは繰り返す。あなたの最終的な結果は何ですか?興味深い質問、良いロードマップが、宛先はありません。 – Parfait

+0

元のデータフレームと目的の結果を追加しました。私はこれが助けて欲しい! – jjvandermade

答えて

2

種類が、ワンライナー私にとってはこれは:

  A   B   C  sum   A   B   C \ 
    geoffrey geoffrey geoffrey geoffrey julian julian julian 
0 0.073676 0.279702 0.258112 0.611490 0.204082 0.795725 0.258185 
1 0.096733 0.541198 0.757652 1.395583 0.263235 0.507324 0.525919 
2 0.028613 0.364365 0.924733 1.317711 0.196243 0.653408 0.174911 
3 0.831569 0.738029 0.294473 1.864071 0.528785 0.654160 0.940831 
4 0.263250 0.855270 0.264698 1.383218 0.853517 0.803087 0.701937 
5 0.069519 0.374411 0.846647 1.290577 0.239797 0.943544 0.189361 
6 0.290414 0.873785 0.118713 1.282912 0.980734 0.850097 0.903645 
7 0.088387 0.062140 0.872064 1.022591 0.591942 0.566298 0.568482 
8 0.061483 0.008404 0.658370 0.728257 0.818167 0.282050 0.449198 
9 0.427602 0.171458 0.234426 0.833486 0.217424 0.471933 0.390549 

     sum 
    julian 
0 1.257992 
1 1.296478 
2 1.024562 
3 2.123776 
4 2.358541 
5 1.372702 
6 2.734476 
7 1.726722 
8 1.549415 
9 1.079906 

私はちょうどここに私のdfだ」と述べ、人々の名前で最初のグループをすることができますし、それを合計し、それから01元に戻ってこれら二つの合計の列を結合しますを入力し、sortlevelを使用してlevel=1axis=1でソートします。

C列の後に「sum」という唯一の理由が表示されるのは、sCの後に来るためです。 xという名前の列があった場合、これは機能しません。しかし、それが重要かどうかは分かりません。

sum_columns = [('sum', name) for name in df.columns.levels[1].tolist()] 
df[sum_columns] = df.groupby(axis=1, level=1).sum() 
df = df.sortlevel(level=1, axis=1) 

sum_columns - この[('sum', 'geoffrey'), ('sum', 'julian')]次のようになります。

は、ここに別のアプローチです:

df = pd.DataFrame({ 
     ('C', 'julian'): [0.258185, 0.52591899999999991, 0.17491099999999998, 0.94083099999999997, 0.70193700000000003, 0.189361, 0.90364500000000003, 0.56848199999999993, 0.44919799999999993, 0.39054899999999998], 
     ('B', 'geoffrey'): [0.27970200000000001, 0.54119799999999996, 0.36436499999999999, 0.73802900000000005, 0.85527000000000009, 0.37441099999999999, 0.87378500000000003, 0.062140000000000001, 0.008404, 0.171458], 
     ('A', 'julian'): [0.20408199999999999, 0.263235, 0.196243, 0.52878500000000006, 0.85351699999999997, 0.23979699999999998, 0.98073399999999999, 0.59194199999999997, 0.81816699999999998, 0.21742399999999998], 
     ('B', 'julian'): [0.79572500000000002, 0.507324, 0.65340799999999999, 0.65416000000000007, 0.803087, 0.94354400000000005, 0.85009699999999988, 0.56629799999999997, 0.28205000000000002, 0.47193299999999999], 
     ('A', 'geoffrey'): [0.073676000000000005, 0.096733, 0.028613, 0.831569, 0.26324999999999998, 0.069519000000000011, 0.29041400000000001, 0.088387000000000007, 0.061483000000000003, 0.42760200000000004], 
     ('C', 'geoffrey'): [0.25811200000000001, 0.75765199999999999, 0.92473300000000003, 0.29447299999999998, 0.26469799999999999, 0.84664699999999993, 0.11871300000000001, 0.87206399999999995, 0.65837000000000001, 0.23442600000000002]}, 
     columns=pd.MultiIndex.from_tuples([('A','julian'),('A','geoffrey'), ('B','julian'),('B','geoffrey'), ('C','julian'),('C','geoffrey')])) 

編集:

ここで私はレクリエーション-の目的のために使用dfです。 sortlevelを使用し、名前の横にある合計欄を有することが望まれます場合

df[sum_columns]はレベル1

にそれぞれの名前のための新しい「和」の列を作成します。

+0

それはきちんとしたものでした! – Zero

+0

驚くばかり!私はこれが機能すると思います(実際の関数とデータフレームはより複雑ですが、なぜこれが転送されないのか分かりません)。本当にありがとう。あなたはなぜ申請がうまくいかなかったのか知っていますか?それでも私の頭を包み込むことを試みています – jjvandermade

+0

あなたの関数 'group = inputDF.columns [0] [1]'は '' julian''という文字列を返します。複数のグループ( 'julian'、 'geoffrey')を持つDataFrameGroupByオブジェクトに関数を適用しているので、おそらくgeoffreyのために行う帽子を知らないでしょうか?私はこれについて間違っているかもしれない。 'addColumn(dataframe)'は '(sum、julian)'列を返しますが、その列の合計は各行のjulianとgeoffreyの合計です。私は人によって合計が欲しいと思うので、あなたの機能は変化する必要があります。私は見る。 – Jarad

関連する問題