我有这样的数据框:
x = pd.DataFrame({
'audio': ['audio1', 'audio1', 'audio2', 'audio2', 'audio3', 'audio3'],
'text': ['text1', 'text2', 'text3', 'text4', 'text5', 'text6'],
'login': ['operator1', 'operator2', 'operator3', 'operator4', 'operator5', 'operator6']
})
我正试图像这样汇总它:
x1 = x.groupby('audio')['text'].agg(
[
('text1', lambda x : x.iat[0]),
('text2', lambda x : x.iat[1]),
('leven', lambda x: Levenshtein.distance(x.iat[0], x.iat[1])) #some function works with grouped text
]
).reset_index()
它可以工作,但我还需要向行添加分组的登录名,以使行像这样:
audio, text1, text2, leven, login1, login2
我尝试了类似lambda x : x.ait[0, 1]
之类的方法,但是它不起作用
答案 0 :(得分:3)
查看您的数据框,我正在考虑旋转数据框,以下是我的方法,该方法利用了 groupby().cumcount()
和 unstack
使用某些列格式来创建数据透视表。
选项1:
然后,您可以使用 df.apply
来应用该功能
m = x.assign(k=x.groupby('audio').cumcount().add(1)).set_index(['audio','k']).unstack()
m.columns=[f"{a}{b}" for a,b in m.columns]
m = m.assign(leven=m.apply(lambda x:
Levenshtein.distance(x['text1'],x['text2']),1)).reset_index()
audio text1 text2 login1 login2 leven
0 audio1 text1 text2 operator1 operator2 1
1 audio2 text3 text4 operator3 operator4 1
2 audio3 text5 text6 operator5 operator6 1
选项2:(我希望这个)
您还可以使用列表推导功能执行相同的操作,只需将最后一行替换为:
m = x.assign(k=x.groupby('audio').cumcount().add(1)).set_index(['audio','k']).unstack()
m.columns=[f"{a}{b}" for a,b in m.columns]
m = m.assign(leven=[Levenshtein.distance(a,b) for
a,b in zip(m['text1'],m['text2'])]).reset_index()
audio text1 text2 login1 login2 leven
0 audio1 text1 text2 operator1 operator2 1
1 audio2 text3 text4 operator3 operator4 1
2 audio3 text5 text6 operator5 operator6 1
选项3:
如果leven
列的位置很重要,则可以使用df.insert
:
m=x.assign(k=x.groupby('audio').cumcount().add(1)).set_index(['audio','k']).unstack()
m.columns=[f"{a}{b}" for a,b in m.columns]
m.insert(2,'leven',[Levenshtein.distance(a,b) for a,b in zip(m['text1'],m['text2'])])
m=m.reset_index()
audio text1 text2 leven login1 login2
0 audio1 text1 text2 1 operator1 operator2
1 audio2 text3 text4 1 operator3 operator4
2 audio3 text5 text6 1 operator5 operator6
答案 1 :(得分:2)
这就是您要寻找的东西
x1 = x.groupby('audio',)['login'].agg(
[
('operator1', lambda x : x.iat[0]),
('operator2', lambda x : x.iat[1]),
('leven', lambda x: Levenshtein.distance(x.iat[0], x.iat[1])) #some function works with grouped text
]
).reset_index()
x2 = x.groupby('audio',)['text'].agg(
[
('text1', lambda x : x.iat[0]),
('text2', lambda x : x.iat[1]),
('leven', lambda x: Levenshtein.distance(x.iat[0], x.iat[1])) #some function works with grouped text
]
).reset_index()
x1.merge(x2)
audio operator1 operator2 leven text1 text2
0 audio1 operator1 operator2 1 text1 text2
1 audio2 operator3 operator4 1 text3 text4
2 audio3 operator5 operator6 1 text5 text6
答案 2 :(得分:0)
当您有很多列时,此解决方案效果很好,它会自动扩展它们,因此您无需手动列出它们。
x = pd.DataFrame({
'audio': ['audio1', 'audio1', 'audio2', 'audio2', 'audio3', 'audio3'],
'text': ['text1', 'text2', 'text3', 'text4', 'text5', 'text6'],
'login': ['operator1', 'operator2', 'operator3', 'operator4', 'operator5', 'operator6']
})
text = x.groupby(['audio']).agg(list)['text'].apply(pd.Series).rename(columns=lambda x: f'text{x+1}')
login = x.groupby(['audio']).agg(list)['login'].apply(pd.Series).rename(columns=lambda x: f'login{x+1}')
text['leven'] = df.apply(lambda x: Levenshtein.distance(x.text1, x.text2), axis=1)
df = text.assign(**login)
text1 text2 leven login1 login2
audio
audio1 text1 text2 1 operator1 operator2
audio2 text3 text4 1 operator3 operator4
audio3 text5 text6 1 operator5 operator6
答案 3 :(得分:0)
您可以像这样简单地修改agg
表达式:
x1 = x.groupby('audio').agg({'text':[
('text1', lambda x : x.iat[0]),
('text2', lambda x : x.iat[1])
('leven', lambda x: Levenshtein.distance(x.iat[0], x.iat[1])) #some function works with grouped text
],
'login': [
('login1', lambda x : x.iat[0]),
('login2', lambda x : x.iat[1])]
}
).droplevel(0,axis=1).reset_index()