Панды: Присоединиться, если значение столбца df1 находится в списке столбца df2 - PullRequest
0 голосов
/ 27 декабря 2018

Предположим, у нас есть два кадра данных Pandas следующим образом:

df1 = pd.DataFrame({'id': ['a', 'b', 'c']})
df1
    id
0   a
1   b
2   c

df2 = pd.DataFrame({'ids': [['b','c'], ['a', 'b'], ['a', 'z']], 
                    'info': ['asdf', 'zxcv', 'sdfg']})
df2
    ids     info
0   [b, c]  asdf
1   [a, b]  zxcv
2   [a, z]  sdfg

Как мне объединить / объединить строки df1 с df2, где df1.id находится в df2.ids?

Другими словами, как мне добиться следующего:

df3
   id   ids     info
0  a    [a, b]  asdf
1  a    [a, z]  sdfg
2  b    [b, c]  asdf
3  b    [a, b]  zxcv
4  c    [b, c]  asdf

А также версия выше, агрегированная на id, например так:

df3
   id   ids               info
0  a    [[a, b], [a, z]]  [asdf, sdfg]
2  b    [[a, b], [b, c]]  [asdf, zxcv]
3  c    [[b, c]]          [asdf]

Я пыталсяследующее:

df1.merge(df2, how = 'left', left_on = 'id', right_on = 'ids')
TypeError: unhashable type: 'list'

df1.id.isin(df2.ids)
TypeError: unhashable type: 'list'

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Использование stack, merge и groupby.agg:

df = df2.set_index('info').ids.apply(pd.Series)\
        .stack().reset_index(0, name='id').merge(df2)\
        .merge(df1, how='right').sort_values('id')\
        .reset_index(drop=True)

print(df)
   info id     ids
0  zxcv  a  [a, b]
1  sdfg  a  [a, z]
2  asdf  b  [b, c]
3  zxcv  b  [a, b]
4  asdf  c  [b, c]

Для агрегирования:

df = df.groupby('id', as_index=False).agg(list)

print(df)
  id          info               ids
0  a  [zxcv, sdfg]  [[a, b], [a, z]]
1  b  [asdf, zxcv]  [[b, c], [a, b]]
2  c        [asdf]          [[b, c]]
0 голосов
/ 27 декабря 2018

Использование -

df2[['id1','id2']] = pd.DataFrame(df2.ids.values.tolist(), index= df2.index)
new_df1 = pd.merge(df1, df2,  how='inner', left_on=['id'], right_on = ['id1'])
new_df2 = pd.merge(df1, df2,  how='inner', left_on=['id'], right_on = ['id2'])
new_df = new_df1.append(new_df2)[['id','ids','info']]

Выход

id  ids info
0   a   [a, b]  zxcv
1   a   [a, z]  sdfg
2   b   [b, c]  asdf
0   b   [a, b]  zxcv
1   c   [b, c]  asdf

Агрегационная часть

new_df.groupby('id')['ids', 'info'].agg(lambda x: list(x))

Выход

ids info
id      
a   [[a, b], [a, z]]    [zxcv, sdfg]
b   [[b, c], [a, b]]    [asdf, zxcv]
c   [[b, c]]    [asdf]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...