Разделить повторный массив на основе значения в одном столбце
Мои реальные данные насчитывают более 10000 элементов. У меня есть сложный массив записей в формате примерно так:
a = (((1., 2., 3.), 4., 'metadata1'),
((1., 3., 5.), 5., 'metadata1'),
((1., 2., 4.), 5., 'metadata2'),
((1., 2., 5.), 5., 'metadata2'),
((1., 3., 8.), 5., 'metadata3'))
Мои столбцы определены dtype = [('coords', '3f4'), ('values', 'f4'), ('meta', 'S10')]
, Я получаю список всех моих возможных мета-значений, выполняя set(a['meta']).
И я хотел бы разбить его на более мелкие списки на основе столбца "мета". В идеале я хотел бы получить результаты, такие как:
a['metadata1'] == (((1., 2., 3.), 4.), ((1., 3., 5.), 5.))
a['metadata2'] == (((1., 2., 4.), 5.), ((1., 2., 5.), 5.))
a['metadata3'] == (((1., 3., 8.), 5.))
или же
a[0] = (((1., 2., 3.), 4., 'metadata1'), ((1., 3., 5.), 5., 'metadata1'))
a[1] = (((1., 2., 4.), 5., 'metadata2'), ((1., 2., 5.), 5., 'metadata2'))
a[2] = (((1., 3., 8.), 5., 'metadata3'))
или любой другой удобно разделенный формат.
Хотя для большого набора данных первое лучше по памяти. Любые идеи о том, как сделать этот раздел? Я видел некоторые другие вопросы здесь, но они все проверяют числовые значения.
1 ответ
Вы всегда можете легко получить доступ к этим строкам с помощью необычного индексирования:
In [34]: a[a['meta']=='metadata2']
Out[34]:
rec.array([(array([ 1., 2., 4.], dtype=float32), 5.0, 'metadata2'),
(array([ 1., 2., 5.], dtype=float32), 5.0, 'metadata2')],
dtype=[('coords', '<f4', (3,)), ('values', '<f4'), ('meta', 'S10')])
Вы можете использовать этот подход для создания поискового словаря для различных мета-типов:
meta_dict = {}
for meta_type in np.unique(a['meta']):
meta_dict[meta_type] = a[a['meta']==meta_type]
Это будет очень неэффективно, если существует большое количество мета-типов.
Более эффективное решение может заключаться в использовании фрейма данных Pandas. У них есть группировка по функциональности, которая выполняет именно ту задачу, которую вы описываете.