GroupBy и агрегат с установленным пересечением - PullRequest
0 голосов
/ 23 января 2019

У меня есть пандас DataFrame со столбцом наборов:

import pandas as pd

df = pd.DataFrame({'group_var': [1,1,2,2], 'sets_var': [set([0, 1]), set([1, 2]), set([3, 4]), set([5, 6, 7])]})
df

   group_var sets_var
0          1      {0, 1}
1          1      {1, 2}
2          2      {3, 4}
3          2   {5, 6, 7}

Я хочу groupby group_var и получить пересечение всех соответствующих наборов sets_var, вот так:

   group_var sets_var
0          1      {1}
1          2      {}

или Сериал, подобный так:

   sets_var
1  {1}
2  {}

Как бы я поступил так элегантно?Производительность - главный приоритет.

1 Ответ

0 голосов
/ 23 января 2019

Используйте groupby, agg и уменьшите с помощью set.intersection.

df.groupby('group_var', as_index=False).agg(lambda x: set.intersection(*x))

   group_var sets_var
0          1      {1}
1          2       {}

Если производительность абсолютно важна, мы можем попытаться избавиться от lambda:

from functools import partial, reduce 
import operator

p = partial(reduce, operator.and_)
df.groupby('group_var', as_index=False).agg(p)

   group_var sets_var
0          1      {1}
1          2       {}

Однако это выполняет только попарное пересечение, поэтому ваш пробег может отличаться.


Или, как серия,

pd.Series({
    k: set.intersection(*g.tolist()) 
    for k, g in df.groupby('group_var')['sets_var']})

1    {1}
2     {}
dtype: object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...