10

次のようなレコードの DataFrame があります。

stocks = pd.Series(['A', 'A', 'B', 'C', 'C'], name = 'stock')
positions = pd.Series([ 100, 200, 300, 400, 500], name = 'positions')
same1 = pd.Series(['AA', 'AA', 'BB', 'CC', 'CC'], name = 'same1')
same2 = pd.Series(['AAA', 'AAA', 'BBB', 'CCC', 'CCC'], name = 'same2')
diff = pd.Series(['A1', 'A2', 'B3' ,'C1', 'C2'], name = 'different')
df = pd.DataFrame([stocks, same1, positions, same2, diff]).T
df

これにより、次のような pandas DataFrame が得られます

      stock same1 positions same2 different
0     A    AA       100   AAA        A1
1     A    AA       200   AAA        A2
2     B    BB       300   BBB        B3
3     C    CC       400   CCC        C1
4     C    CC       500   CCC        C2

「異なる」列のデータには興味がなく、他の一意の列に沿って位置を合計したいと考えています。私は現在それをやっています:

df.groupby(['stock','same1','same2'])['positions'].sum()

与える:

stock  same1  same2
A      AA     AAA      300
B      BB     BBB      300
C      CC     CCC      900
Name: positions

問題は、これが pd.Series (マルチインデックス付き) であることです。現在、私はそれを繰り返して DataFrame を再度構築しています。私は方法が欠けていると確信しています。基本的に、DataFrame から 1 列を削除してから「再構築」して、1 つの列が合計され、残りのフィールド (同じ) が所定の位置に留まるようにします。

空の位置がある場合、この groupby メソッドは中断します。そのため、現在、DataFrame に対する精巧な反復を使用して、新しいものを構築しています。より良いアプローチはありますか?

4

1 に答える 1

10

ステップ 1. ['positions'] の代わりに [['positions']] を使用します。

In [30]: df2 = df.groupby(['stock','same1','same2'])[['positions']].sum()

In [31]: df2 
Out[31]: 

                   positions
stock same1 same2               
A     AA    AAA          300 
B     BB    BBB          300 
C     CC    CCC          900 

ステップ 2. 次に、 を使用reset_indexしてインデックスを列に戻します

In [34]: df2.reset_index()
Out[34]: 
  stock same1 same2  positions
0     A    AA   AAA        300 
1     B    BB   BBB        300 
2     C    CC   CCC        900

編集

私の方法はあまり良くないようです。

@Andy と @unutbu のおかげで、よりエレガントな方法で目標を達成できます。

方法 1:

df.groupby(['stock', 'same1', 'same2'])['positions'].sum().reset_index()

方法 2:

df.groupby(['stock', 'same1', 'same2'], as_index=False)['positions'].sum()
于 2013-06-18T10:37:41.197 に答える