如何在 pandas 数据框中从 groupby 的结果生成所有值对
Posted
技术标签:
【中文标题】如何在 pandas 数据框中从 groupby 的结果生成所有值对【英文标题】:How generate all pairs of values, from the result of a groupby, in a pandas dataframe 【发布时间】:2018-05-17 01:32:17 【问题描述】:我有一个熊猫数据框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))
获取所有可能的成对组合。但是,对于生成如上所示的结果数据帧的最佳方式,我有点迷茫。
【问题讨论】:
我已经编辑了标题以更好地反映您要解决的实际问题。 不,新标题与我想要的无关...不过感谢您的努力... 可能重复:***.com/questions/43800390/… 是的,我的 itertools 部分是正确的。 :) 我需要弄清楚如何在 groupby 中做到这一点。我正在为每个 ID 做这件事。 【参考方案1】:它在 apply 和 stack 中简单使用 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)
【讨论】:
严格来说,看起来结果应该在 OP 中分成两列,这是另一个步骤吗?我很好奇这一切最终是否比仅仅建立一个新的df更有效?apply
不会在这里作为 python 循环运行吗?
啊,我写第一条评论的速度太慢了:进一步:)
嗯,看来DataFrame
从apply
返回更好;)【参考方案2】:
您可以将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
【讨论】:
【参考方案3】:您可以定义应用于每个组的自定义函数。输入和输出都是一个数据框:
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
【讨论】:
【参考方案4】:最简单的方法是:
from itertools import combinations
import pandas as pd
df_new = pd.DataFrame(list(combinations(df.words, 2)), columns=['word1', 'word2'])
【讨论】:
以上是关于如何在 pandas 数据框中从 groupby 的结果生成所有值对的主要内容,如果未能解决你的问题,请参考以下文章
如何对一列执行 pandas groupby 操作,但将另一列保留在结果数据框中
Python Pandas 如何将 groupby 操作结果分配回父数据框中的列?
如何在python中使用groupby或pivot在这个pandas数据框中[重复]
将列的名称保留在 groupby 中,并在 pandas 数据框中使用 sum