Объедините несколько групповых групп со столбцом списков в Pandas - PullRequest
0 голосов
/ 18 октября 2018

У меня есть DataFrame, у которого есть подмножество, которое выглядит следующим образом:

{u'snId': {3: u'396321357429208',
  695: u'606426623024865',
  703: u'606426623024865',
  914: u'606426623024865',
  5097: u'606426623024865',
  6865: u'396321357429208',
  26884: u'606426623024865',
  30538: u'396321357429208',
  32152: u'606426623024865',
  34314: u'396321357429208',
  34345: u'606426623024865',
  52207: u'606426623024865',
  55361: u'396321357429208',
  59077: u'606426623024865',
  68118: u'396321357429208',
  79366: u'396321357429208',
  86798: u'606426623024865',
  130472: u'396321357429208',
  146595: u'396321357429208',
  211110: u'606426623024865',
  227155: u'396321357429208',
  240219: u'396321357429208',
  245716: u'606426623024865',
  248525: u'606426623024865',
  327256: u'606426623024865'},
 u'snMsgType': {3: u'Private',
  695: u'Private',
  703: u'Private',
  914: u'Private',
  5097: u'Private',
  6865: u'Private',
  26884: u'Private',
  30538: u'Private',
  32152: u'Private',
  34314: u'Private',
  34345: u'Private',
  52207: u'Private',
  55361: u'Private',
  59077: u'Private',
  68118: u'Private',
  79366: u'Private',
  86798: u'Private',
  130472: u'Private',
  146595: u'Private',
  211110: u'Private',
  227155: u'Private',
  240219: u'Private',
  245716: u'Private',
  248525: u'Private',
  327256: u'Private'},
 u'tagIds': {3: array([198419]),
  695: array([201340]),
  703: array([198419]),
  914: array([198421]),
  5097: array([202750]),
  6865: array([199783]),
  26884: array([198419, 202750]),
  30538: array([198382]),
  32152: array([188101]),
  34314: array([198419, 198416]),
  34345: array([198419, 201340]),
  52207: array([201340]),
  55361: array([202750]),
  59077: array([198419, 198421]),
  68118: array([198422]),
  79366: array([188101]),
  86798: array([202750]),
  130472: array([198408]),
  146595: array([198419, 188101]),
  211110: array([198419, 199783]),
  227155: array([201340]),
  240219: array([198419, 199783]),
  245716: array([199783]),
  248525: array([198419, 198416]),
  327256: array([198419, 188101])},
 u'text': {3: u"No problem!",
  695: u"If you're struggling on what other shapewear to buy, then this article will help.",
  703: u"No problem!",
  914: u"No problem!",
  5097: u"No problem!",
  6865: u"No problem!",
  26884: u"No problem!",
  30538: u"No problem!",
  32152: u"No problem!",
  34314: u"No problem!",
  34345: u"No problem!",
  52207: u"No problem!",
  55361: u"No problem!",
  59077: u"No problem!",
  68118: u"No problem!",
  79366: u"No problem!",
  86798: u"If you're struggling on what other shapewear to buy, then this article will help.",
  130472: u"No problem!",
  146595: u"No problem!",
  211110: u"No problem!",
  227155: u"No problem!",
  240219: u"No problem!",
  245716: u"No problem!",
  248525: u"No problem!",
  327256: u"No problem!"}}

Я хочу сделать групповую операцию по столбцам snId, text и snMsgType и объединить всеуникальный tagIds в список для каждой группы.

Я использовал следующее:

df.groupby(["snId","snMsgType","text"]).agg({'tagIds': lambda x:  list(set(sum(filter(None, x), [])))})

Однако это не работает для всего DataFrame, так как есть группы, которые толькоимеют 1 ряд и не уменьшены.Я получаю ValueError: Function does not reduce.Задача состоит в том, чтобы сделать эту работу для всех групп, независимо от того, уменьшает она или нет.

Приношу свои извинения за несколько запутанную формулировку проблемы и большой текстовый блок.

Ответ будет выглядеть примерно так:

{'snId': {0: u'396321357429208', 1: u'606426623024865', 2:u'606426623024865'},
 'snMsgType': {0: u'Private', 1: u'Private', 2:'Private'},
 'tagIds': {0: [188101,
   199783,
   198408,
   198382,
   198416,
   198419,
   198422,
   201340,
   202750],
  1: [188101, 199783, 198416, 198419, 198421, 201340, 202750]},
  2: [201340, 202750]
 'text': {0: u"No problem!",
  1: u"No problem!",
  2: u"If you're struggling on what other shapewear to buy, then this article will help."}}

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Я обманул это, используя:

def aggr_tags(df):
    myagg = lambda s:tuple(i for i in zip(*s)) 
    # Group by snIds and aggregate all the tags ids used..
    df = df.groupby(["snId","snMsgType","text"]).agg({'tagIds': myagg})

    #convert back to lists.
    df['tagIds'] = df['tagIds'].apply(lambda x: list(set(x[0])))

    return df.reset_index()
0 голосов
/ 18 октября 2018

IIUC, сначала вам нужно развернуть столбец tagIds списков в отдельные строки, затем вы можете выполнить groupby() и agg(), где my_dict - ваш ввод dict:

df = pd.DataFrame(my_dict)

s = df.apply(lambda x: pd.Series(x['tagIds']), axis=1).stack().reset_index(level=1, drop=True).astype(int)
s.name = 'tagIds'

df = df.drop('tagIds', axis=1).join(s)

g = df.groupby(["snId","snMsgType","text"]).agg({'tagIds': lambda x: x.tolist()})

Выход:

                                                                                                                         tagIds
snId            snMsgType text                                                                                                 
396321357429208 Private   No problem!                                         [198419, 199783, 198382, 198419, 198416, 20275...
606426623024865 Private   If you're struggling on what other shapewear to...                                   [201340, 202750]
                          No problem!                                         [198419, 198421, 202750, 198419, 202750, 18810...

Возвращает фрейм данных MultiIndex.Если вы хотите вернуть результаты в формате отредактированного вопроса, вы можете сделать следующее:

g.reset_index().to_dict()

Выход:

{'snId': {0: '396321357429208', 1: '606426623024865', 2: '606426623024865'}, 'snMsgType': {0: 'Private', 1: 'Private', 2: 'Private'}, 'text': {0: 'No problem!', 1: "If you're struggling on what other shapewear to buy, then this article will help.", 2: 'No problem!'}, 'tagIds': {0: [198419, 199783, 198382, 198419, 198416, 202750, 198422, 188101, 198408, 198419, 188101, 201340, 198419, 199783], 1: [201340, 202750], 2: [198419, 198421, 202750, 198419, 202750, 188101, 198419, 201340, 201340, 198419, 198421, 198419, 199783, 199783, 198419, 198416, 198419, 188101]}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...