Как генерировать все пары значений из результата groupby в фрейме данных pandas
у меня есть фрейм данных pandas df
:
ID words
1 word1
1 word2
1 word3
2 word4
2 word5
3 word6
3 word7
3 word8
3 word9
Я хочу создать другой фрейм данных, который будет генерировать все пары слов в каждой группе. Таким образом, результат для вышеизложенного будет:
ID wordA wordB
1 word1 word2
1 word1 word3
1 word2 word3
2 word4 word5
3 word6 word7
3 word6 word8
3 word6 word9
3 word7 word8
3 word7 word9
3 word8 word9
Я знаю, что я могу использовать df.groupby['words']
чтобы получить слова в каждую ID
.
Я знаю, что я могу использовать
iterable = ['word1','word2','word3']
list(itertools.combinations(iterable, 2))
чтобы получить все возможные попарные комбинации. Тем не менее, я немного потерян относительно лучшего способа создания результирующего фрейма данных, как показанный выше.
3 ответов
его простое использование комбинаций itertools внутри apply и stack i.e
from itertools import combinations
ndf = df.groupby('ID')['words'].apply(lambda x : list(combinations(x.values,2)))
.apply(pd.Series).stack().reset_index(level=0,name='words')
ID words
0 1 (word1, word2)
1 1 (word1, word3)
2 1 (word2, word3)
0 2 (word4, word5)
0 3 (word6, word7)
1 3 (word6, word8)
2 3 (word6, word9)
3 3 (word7, word8)
4 3 (word7, word9)
5 3 (word8, word9)
чтобы соответствовать вам точный выход дальше мы должны сделать
sdf = pd.concat([ndf['ID'],ndf['words'].apply(pd.Series)],1).set_axis(['ID','WordsA','WordsB'],1,inplace=False)
ID WordsA WordsB
0 1 word1 word2
1 1 word1 word3
2 1 word2 word3
0 2 word4 word5
0 3 word6 word7
1 3 word6 word8
2 3 word6 word9
3 3 word7 word8
4 3 word7 word9
5 3 word8 word9
преобразовать в одну строку мы можем сделать :
combo = df.groupby('ID')['words'].apply(combinations,2)\
.apply(list).apply(pd.Series)\
.stack().apply(pd.Series)\
.set_axis(['WordsA','WordsB'],1,inplace=False)\
.reset_index(level=0)
можно использовать groupby
С apply
и возврат DataFrame
, последней добавить reset_index
для удаления второго уровня, а затем для создания столбца с индексом:
from itertools import combinations
f = lambda x : pd.DataFrame(list(combinations(x.values,2)),
columns=['wordA','wordB'])
df = (df.groupby('ID')['words'].apply(f)
.reset_index(level=1, drop=True)
.reset_index())
print (df)
ID wordA wordB
0 1 word1 word2
1 1 word1 word3
2 1 word2 word3
3 2 word4 word5
4 3 word6 word7
5 3 word6 word8
6 3 word6 word9
7 3 word7 word8
8 3 word7 word9
9 3 word8 word9
Вы можете определить пользовательскую функцию, которая применяется к каждой группе. Как вход, так и выход представляют собой фрейм данных:
def combine(group):
return pd.DataFrame.from_records(itertools.combinations(group.word, 2))
df.groupby('ID').apply(combine)
результат:
0 1
ID
1 0 word1 word2
1 word1 word3
2 word2 word3
2 0 word4 word5
3 0 word6 word7
1 word6 word8
2 word6 word9
3 word7 word8
4 word7 word9
5 word8 word9