I struggled with the problem of grouping, combinations, and transformation. My current solution:
df = df.groupby(level='lvl_2').transform(lambda x: x[0]/x[1])
But this does not affect some parts of my problems.
Assuming the following code:
import pandas as pd
import numpy as np
import datetime
today = datetime.date.today()
today_1 = datetime.date.today() - datetime.timedelta(1)
today_2 = datetime.date.today() - datetime.timedelta(2)
ticker_date = [('first', 'a',today), ('first', 'a',today_1), ('first', 'a',today_2),
('first', 'c',today), ('first', 'c',today_1), ('first', 'c',today_2),
('first', 'b',today), ('first', 'b',today_1), ('first', 'b',today_2),
('first', 'd',today), ('first', 'd',today_1), ('first', 'd',today_2)]
index_df = pd.MultiIndex.from_tuples(ticker_date,names=['lvl_1','lvl_2','lvl_3'])
df = pd.DataFrame(np.random.rand(12), index_df, ['idx'])
Conclusion:
idx
lvl_1 lvl_2 lvl_3
first a 2018-02-14 0.421075
2018-02-13 0.278418
2018-02-12 0.117888
c 2018-02-14 0.716823
2018-02-13 0.241261
2018-02-12 0.772491
b 2018-02-14 0.681738
2018-02-13 0.636927
2018-02-12 0.668964
d 2018-02-14 0.770797
2018-02-13 0.11469
2018-02-12 0.877965
I need the following:
- Get a new multi-index frame with possible combinations of lvl_2 elements.
- Convert my data to get the ratio of each element
Here is an illustration:
Here I created a new column.
new
lvl_1 lvl_2 lvl_3
first a/c 2018-02-14 0.587418372
2018-02-13 1.154011631
2018-02-12 0.152607603
a/b 2018-02-14 0.617649302
2018-02-13 0.437127018
2018-02-12 0.17622473
a/d 2018-02-14 0.546285209
2018-02-13 2.427569971
2018-02-12 0.134274145
c/b 2018-02-14 1.051464052
2018-02-13 0.378789092
2018-02-12 1.154757207
c/d 2018-02-14 0.929976375
2018-02-13 2.103592292
2018-02-12 0.87986537
b/d 2018-02-14 0.884458554
2018-02-13 5.553465865
2018-02-12 0.761948369
For further explanation:
new
lvl_1 lvl_2 lvl_3
first a/c 2018-02-14 0.587418372
2018-02-13 1.154011631
2018-02-12 0.152607603
Here I am doing the ratio of the elements a to c:
0.587418 = 0.421075/0.716823
1.154012 = 0.278418/0.241261
0.152608 = 0.117888/0.772491
I tried the groupby and transform method, something like:
df = df.groupby(level='lvl_2').transform(lambda x: x[0]/x[1])
But, obviously, this only transforms the first and second meaning of each particular level. In addition, I do not know how to install a new multi-index with combinations. (a / c, a / b, a / d, c / b, c / d, b / d)
, , .