Python 如何从数据帧中的groupby结果生成所有值对
我有一个熊猫数据帧Python 如何从数据帧中的groupby结果生成所有值对,python,python-2.7,pandas,combinations,Python,Python 2.7,Pandas,Combinations,我有一个熊猫数据帧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
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))
以获得所有可能的成对组合。但是,对于生成如上所示的结果数据帧的最佳方法,我有点不知所措。它的简单用法是应用和堆栈中的itertools组合,即
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)
可以定义应用于每个组的自定义函数。输入和输出都是数据帧:
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
from itertools import combinations
import pandas as pd
df_new = pd.DataFrame(list(combinations(df.words, 2)), columns=['word1', 'word2'])
您可以与apply
一起使用,并返回DataFrame
,最后一次添加用于删除第二级,然后用于从索引创建列:
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
最简单的方法是:
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
from itertools import combinations
import pandas as pd
df_new = pd.DataFrame(list(combinations(df.words, 2)), columns=['word1', 'word2'])
我对标题进行了编辑,以更好地反映您试图解决的实际问题。不,新标题与我想要的内容无关。。。谢谢你的努力……可能重复:是的,我把itertools部分做对了。:)我需要弄清楚如何在groupby中进行。我对每个ID都这样做。严格来说,结果应该在OP中分成两列,这是另一个步骤?我很好奇,这一切是否比仅仅建立一个新的df更有效?在这里,
apply
不会作为python循环运行吗?啊,我写第一条评论的速度很慢:下一步:)嗯,似乎从apply
返回DataFrame
;)