У меня есть фрейм данных со следующей структурой.
Чего я хочу добиться, так это сгруппировать фрейм данных по уровню первичного индекса (TCKRA
и TCKRB
), а затем внутри каждого применить функцию, которая вычислит ASK - BID
и выведет только два столбца для каждого уровня.
df = pd.DataFrame(np.random.rand(10, 4))*100
df.columns = pd.MultiIndex.from_tuples([('TCKR_A', 'BID'), ('TCKR_A', 'ASK'),
('TCKR_B', 'BID'), ('TCKR_B', 'ASK')])
df.columns.names = ['Sec', 'Fld']
df
>> df
Sec TCKR_A TCKR_B
Fld BID ASK BID ASK
0 8.183207 36.627854 51.926086 18.809108
1 79.111061 39.580137 56.137122 41.631460
2 48.757876 11.297864 50.613713 56.089854
3 12.320957 38.624896 81.759719 88.549522
4 8.659632 36.967937 50.086826 20.728593
5 56.019027 77.685117 60.440403 9.726945
6 47.956368 20.087774 31.204852 99.893489
7 21.328761 32.824996 14.175482 13.154170
8 13.344390 90.940015 7.617241 50.501808
9 64.513930 34.020330 50.607016 38.710182
Я пытаюсь избежать использования цикла, хотя тогда это выполнимо, поскольку я могу применить операцию для каждого основного уровня.
До сих пор я пытался использовать pd.df.groupby()
, но безуспешно,
df.groupby('Security', level=0).apply(lambda x: x.ASK - x.BID)
>> AttributeError: 'DataFrame' object has no attribute 'ASK'
Здесь группировка не нужна, потому что Multiindex
и возможно выбрать столбцы по DataFrame.xs
для DataFrames с одинаковыми именами столбцов по первому уровню MultiIndex
, поэтому можно вычесть:
df1 = df.xs('ASK', level=1, axis=1) - df.xs('BID', level=1, axis=1)
print (df1)
Sec TCKR_A TCKR_B
0 -51.040171 1.390744
1 -58.132705 20.100789
2 -47.563213 -18.537630
3 72.634983 83.624726
4 48.298953 68.488183
5 6.468167 53.791475
6 -42.180559 -23.153447
7 -3.664986 3.900489
8 14.290560 -10.863276
9 -5.373369 11.897776
Деталь:
print (df.xs('ASK', level=1, axis=1))
Sec TCKR_A TCKR_B
0 39.308051 63.787740
1 29.917202 90.320616
2 40.574980 26.707032
3 88.921470 98.472349
4 51.535075 88.601087
5 57.830159 83.719740
6 10.484424 4.659494
7 47.242629 94.349222
8 84.629795 81.936188