3

次のような情報を含む Pandas データフレームが 1 つあります。

index       year  month day symbol transaction  nr_shares
2011-01-10  2011  1     10  AAPL       Buy       1500
2011-01-13  2011  1     13  GOOG       Sell      1000

そして、ゼロで埋められた 2 番目の Pandas データフレームを埋めたいと思います

index        AAPL  GOOG
2011-01-10     0     0
2011-01-11     0     0
2011-01-12     0     0
2011-01-13     0     0

最初のデータフレームからの情報を使用して取得します

index        AAPL  GOOG
2011-01-10   1500    0
2011-01-11     0     0
2011-01-12     0     0
2011-01-13     0  -1000

関連する日付に、指定された株式数の売買取引が適切な列に入力されていることがわかります。買い注文は正の数、売り注文は負の数です。

どうすればこれを達成できますか? 最初のデータフレーム インデックスをループし、ネストされた "if" ステートメントを使用してシンボルとトランザクション列をチェックしてから、2 番目のデータフレームに書き込む必要がありますか、それとも使用できるより洗練されたデータフレーム メソッドがありますか?

4

2 に答える 2

4

を使用できますpivot_table。から始めて(少し複雑になるように編集):

>>> df1
        index  year  month  day symbol transaction  nr_shares
0  2011-01-10  2011      1   10   AAPL         Buy       1500
1  2011-01-10  2011      1   10   AAPL        Sell        200
2  2011-01-10  2011      1   10   GOOG        Sell        500
3  2011-01-10  2011      1   10   GOOG         Buy        600
4  2011-01-13  2011      1   13   GOOG        Sell       1000
>>> df2
        index  AAPL  GOOG
0  2011-01-10     0     0
1  2011-01-11     0     0
2  2011-01-12     0     0
3  2011-01-13     0     0

共有に署名できます。

>>> df1["nr_shares"] = df1.apply(lambda row: row["nr_shares"] * (-1 if row["transaction"] == "Sell" else 1), axis=1)
>>> df1
        index  year  month  day symbol transaction  nr_shares
0  2011-01-10  2011      1   10   AAPL         Buy       1500
1  2011-01-10  2011      1   10   AAPL        Sell       -200
2  2011-01-10  2011      1   10   GOOG        Sell       -500
3  2011-01-10  2011      1   10   GOOG         Buy        600
4  2011-01-13  2011      1   13   GOOG        Sell      -1000

そして、ピボットできますdf1。デフォルトでは、集計値の平均が使用されますが、合計が必要です。

>>> a = df1.pivot_table(values="nr_shares", rows="index", cols="symbol",
                    aggfunc=sum)
>>> a
symbol      AAPL  GOOG
index                 
2011-01-10  1300   100
2011-01-13   NaN -1000

b同じインデックスを与える:

>>> b = df2.set_index("index")
>>> b
            AAPL  GOOG
index                 
2011-01-10     0     0
2011-01-11     0     0
2011-01-12     0     0
2011-01-13     0     0

そして、それらを追加します:

>>> (a+b).fillna(0)
symbol      AAPL  GOOG
index                 
2011-01-10  1300   100
2011-01-11     0     0
2011-01-12     0     0
2011-01-13     0 -1000
于 2013-03-29T18:35:53.487 に答える
3

最初applyに、署名された株式を含む列を追加できます (買いの場合はプラス、売りの場合はマイナス):

In [11]: df['signed_shares'] = df.apply(lambda row: row['nr_shares']
                                                    if row['transaction'] == 'Buy'
                                                    else -row['nr_shares'],
                                        axis=1)

In [12]: df
Out[12]: 
            year  month  day symbol transaction  nr_shares  signed_shares
index                                                                    
2011-01-10  2011      1   10   AAPL         Buy       1500           1500
2011-01-13  2011      1   13   GOOG        Sell       1000          -1000

関心のある列だけを使用して、それらをアンスタックします。

In [13]: df[['symbol', 'signed_shares']].set_index('symbol', append=True)
Out[13]: 
                   signed_shares
index      symbol               
2011-01-10 AAPL             1500
2011-01-13 GOOG            -1000

In [14]: a = df[['symbol', 'signed_shares']].set_index('symbol', append=True).unstack()

In [15]: a
Out[15]: 
            signed_shares      
symbol               AAPL  GOOG
index                          
2011-01-10           1500   NaN
2011-01-13            NaN -1000

好きな日付範囲でインデックスを再作成します。

In [16]: rng = pd.date_range('2011-01-10', periods=4)

In [17]: a.reindex(rng)
Out[17]: 
            signed_shares      
symbol               AAPL  GOOG
2011-01-10           1500   NaN
2011-01-11            NaN   NaN
2011-01-12            NaN   NaN
2011-01-13            NaN -1000

最後に、以下を使用して NaN に 0 を入力しますfillna

In [18]: a.reindex(rng).fillna(0)
Out[18]: 
            signed_shares      
symbol               AAPL  GOOG
2011-01-10           1500     0
2011-01-11              0     0
2011-01-12              0     0
2011-01-13              0 -1000

@DSM が指摘しているように、[13]-[15] を次のように使用すると、より適切に実行できますpivot_table

In [20]: df.reset_index().pivot_table('signed_shares', 'index', 'symbol')
Out[20]: 
symbol      AAPL  GOOG
index                 
2011-01-10  1500   NaN
2011-01-13   NaN -1000
于 2013-03-29T18:36:40.890 に答える