Сгруппировать по уровню основного столбца в DataFrame, а затем применить функцию на каждом подуровне. - PullRequest
1 голос
/ 27 мая 2019

У меня есть датафрейм со следующей структурой.Чего я хочу добиться, так это сгруппировать фрейм данных по уровню первичного индекса (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'

1 Ответ

3 голосов
/ 27 мая 2019

Здесь группировка не обязательна, поскольку Multiindex и возможные столбцы можно выбрать DataFrame.xs для фреймов данных с одинаковыми именами столбцов по первому уровню 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

Detail :

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
...