Эксперимент 1: выбор из DataFrame с индексом диапазона по умолчанию -
In [167]: df_range = pd.read_csv('extract.csv')
In [168]: df_range
Out[168]:
frame face lmark x y
0 1 NaN NaN NaN NaN
1 2 NaN NaN NaN NaN
2 3 NaN NaN NaN NaN
3 4 NaN NaN NaN NaN
4 5 NaN NaN NaN NaN
... ... ... ... .. ..
312809 5146 NaN NaN NaN NaN
312810 5147 NaN NaN NaN NaN
312811 5148 NaN NaN NaN NaN
312812 5149 NaN NaN NaN NaN
312813 5150 NaN NaN NaN NaN
[312814 rows x 5 columns]
выбор значений индекса, исключая frame
5148 -
In [170]: ind = df_range.loc[(df_range['frame'] != 5148)].index.values
In [171]: ind
Out[171]: array([ 0, 1, 2, ..., 312810, 312812, 312813])
выбор записей из df_range
исключая frame
5148 -
In [173]: df_range.loc[ind]
Out[173]:
frame face lmark x y
0 1 NaN NaN NaN NaN
1 2 NaN NaN NaN NaN
2 3 NaN NaN NaN NaN
3 4 NaN NaN NaN NaN
4 5 NaN NaN NaN NaN
... ... ... ... .. ..
312808 5145 NaN NaN NaN NaN
312809 5146 NaN NaN NaN NaN
312810 5147 NaN NaN NaN NaN
312812 5149 NaN NaN NaN NaN
312813 5150 NaN NaN NaN NaN
[312813 rows x 5 columns]
In [174]: timeit df_range.loc[ind]
14.1 ms ± 12.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Эксперимент 2: выбор из DataFrame с MuitiIndex -
In [177]: df_multi = pd.read_csv('extract.csv').set_index(['frame', 'face', 'lmark'])
In [178]: df_multi
Out[178]:
x y
frame face lmark
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
... .. ..
5146 NaN NaN NaN NaN
5147 NaN NaN NaN NaN
5148 NaN NaN NaN NaN
5149 NaN NaN NaN NaN
5150 NaN NaN NaN NaN
[312814 rows x 2 columns]
выбор значений кадра, исключая frame
5148 -
In [215]: frames = df_range.loc[ind]['frame'].drop_duplicates().values
In [216]: frames
Out[216]: array([ 1, 2, 3, ..., 5147, 5149, 5150])
выбор записей из df_multi
, исключая frame
5148 -
In [218]: df_multi.loc[frames]
Out[218]:
x y
frame face lmark
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
... .. ..
5145 NaN NaN NaN NaN
5146 NaN NaN NaN NaN
5147 NaN NaN NaN NaN
5149 NaN NaN NaN NaN
5150 NaN NaN NaN NaN
[312813 rows x 2 columns]
In [219]: timeit df_multi.loc[frames]
7.83 s ± 607 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Заключение
Оба метода выбирают правильный результат установлен, но фильтрация DataFrame с MultiIndex выглядит на несколько порядков медленнее, чем при использовании индекса диапазона по умолчанию. Вы согласны?
Обновление 13-03-2020 @ALollz - спасибо за вдохновение. Вот гораздо более быстрый способ фильтрации DataFrame с помощью MultiIndex -
In [40]: timeit df_multi.loc[df_multi.index.get_level_values('frame') != 5148]
4.53 ms ± 15.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [41]: df_multi.loc[df_multi.index.get_level_values('frame') != 5148]
Out[41]:
x y
frame face lmark
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
... .. ..
5145 NaN NaN NaN NaN
5146 NaN NaN NaN NaN
5147 NaN NaN NaN NaN
5149 NaN NaN NaN NaN
5150 NaN NaN NaN NaN
[312813 rows x 2 columns]