0

私はこのような Pandas DataFrame を持っています (これは三角裁定問題です)

>>> df_diff_rel
          a         b         c         d
a -0.833333 -1.666667 -2.500000  0.833333
b  0.000000 -0.840336 -1.680672  1.680672
c -1.652893 -2.479339 -3.305785  0.000000
d -2.459016 -3.278689 -4.098361 -0.819672

正の値の行名と列名を知る必要があります (最大値から最小値にソートされます)

私の例では、取得したい

1.680672 b d
0.833333 a d
0        b a
0        c d

これは私がしました

lst_arbitrage_opportunities = list(df_diff_rel[df_diff_rel>0])
lst_arbitrage_opportunities.sort(reverse=True)

しかし、特定の値の行と列の名前を取得する方法がわかりません。

私のサンプルを取得するための完全なコードは次のとおりです。

import pandas as pd
import numpy as np


class Ticker:
  def __init__(self, ask=None, bid=None):
    self.ask = ask
    self.bid = bid

  def spread(self):
    return(self.ask-self.bid)

  def __repr__(self):
    str = """ask: {ask}
bid: {bid}""".format(ask=self.ask, bid=self.bid)

    if self.ask!=None and self.bid!=None:
      str = str + """
spread: {spread}""".format(spread=self.spread())

    return(str)

markets = ['a', 'b', 'c', 'd']

markets_tickers = dict()
markets_tickers['a'] = Ticker(1.20, 1.19)
markets_tickers['b'] = Ticker(1.19, 1.18)
markets_tickers['c'] = Ticker(1.21, 1.17)
markets_tickers['d'] = Ticker(1.22, 1.21)

df_ask = pd.DataFrame(index=markets, columns=markets)
df_bid = pd.DataFrame(index=markets, columns=markets)

size = 1.0

for mk in markets:
  print("="*5+mk+"="*5)
  print(markets_tickers[mk])
  df_ask.ix[mk]=markets_tickers[mk].ask
  df_bid[mk]=markets_tickers[mk].bid

df_diff_abs = (df_bid - df_ask)*size
df_diff_rel = (df_bid - df_ask)/df_ask*100.0

df_arbitrage_opportunities = df_diff_rel>0

lst_arbitrage_opportunities = list(df_diff_rel[df_diff_rel>0])
lst_arbitrage_opportunities.sort(reverse=True)

print("Ask")
print(df_ask)
print("Bid")
print(df_bid)
print("Diff abs")
print(df_diff_abs)
print("Diff rel")
print(df_diff_rel)
print("Arbitrage opportunities")
print(df_arbitrage_opportunities)
print("List of opportunities (from the best to the worst)")
print(lst_arbitrage_opportunities)
4

1 に答える 1

4

簡単な1行のソリューションは次のとおりです。

必要な形でデータを取得するには、unstackメソッドを使用できます。

In [2]: df.unstack()
Out[2]:
a  a   -0.833333
   b    0.000000
   c   -1.652893
   d   -2.459016
b  a   -1.666667
   b   -0.840336
   c   -2.479339
...

次に、このリストを次のようにフィルタリングして、値> = 0を見つけることができます:

In [3]: df.unstack()[df.unstack() >= 0]
Out[3]:
a  b    0.000000
d  a    0.833333
   b    1.680672
   c    0.000000

最後に、上記のオブジェクトのインデックスにアクセスして、ラベルのリストを返すことができます。

In [1]: df.unstack()[df.unstack() >= 0].index.tolist()
Out[1]: [('a', 'b'), ('d', 'a'), ('d', 'b'), ('d', 'c')]

アップデート:

降順で並べ替えるには、次のSeries.order代わりにメソッドを使用しsortます。

In [1]: tmp = df.unstack()[df.unstack() >= 0]

In [2]: tmp = tmp.order(ascending=False)

In [3]: tmp
Out[3]:
d  b    1.680672
   a    0.833333
   c    0.000000
a  b    0.000000

In [4]: tmp.index.tolist()
Out[4]: [('d', 'b'), ('d', 'a'), ('d', 'c'), ('a', 'b')]
于 2013-03-03T22:20:14.967 に答える