Pandas:groupby后跟aggregate-连接字符串时出现意外行为



具有包含两列类型为str:的pandas数据帧

group   sc  wc
0   1       A   word1
1   2       B   word2
2   2       C   word3
3   1       D   word4

其创建如下:

df = pd.DataFrame({"group":[1,2,2,1],"sc":["A","B","C","D"],"wc":["word1", "word2", "word3","word4"]})

当按group分组并连接各个列时,我可以使用:

df.groupby("group",as_index=False).agg(lambda x: '|'.join(x))
group   sc  wc
0   1   A|D word1|word4
1   2   B|C word2|word3

但是,当指定单列(wc(对执行此操作时

df.groupby("group",as_index=False)["wc"].agg(lambda x: '|'.join(x))
group   wc
0   1   group|sc|wc
1   2   group|sc|wc

其在列名上看起来是CCD_ 6但为什么要这样处理呢

正确的实现将使用apply:

df.groupby("group",as_index=False)["wc"].apply(lambda x: '|'.join(x))
group   wc
0   1   word1|word4
1   2   word2|word3

我偶然发现了这一点,因为我想避免由于性能问题而应用更大的数据帧(在我的情况下,使用aggapply的速度提高了4倍(。

实际要做的是scwc的每个值都有一个join,然后将这些组组合成一个单独的字符串,如:

df["merged"] = df.sc + "|" + df.wc
df.groupby("group",as_index=False).agg('|'.join))
group   sc  wc  merged
0   1   A|D word1|word4 A|word1|D|word4
1   2   B|C word2|word3 B|word2|C|word3

一旦使用整数,它还有更多:

df = pd.DataFrame({"group":[1,2,2,1],"sc":[3,33,333,3333],"wc":[1,10,100,1000]})
df["merged"] = df.sc.astype(str) + "|" + df.wc.astype(str)
df.groupby(["group"],as_index=False).agg('|'.join)
group   merged
0   1   3|1|3333|1000
1   2   33|10|333|100

这表示join仅在字符串列上运行。

连续的joinagg为我节省了很多计算时间,但感觉不太好。欢迎任何见解!

我很确定这是一个与GroupBy.agg相关的错误,因为as_index=False而显现出来——整个子组DataFrame都传递给agg。去掉它,输出就如预期的那样。

df.groupby("group")["wc"].agg('|'.join).reset_index()

group           wc
0      1  word1|word4
1      2  word2|word3

当子组及其列被传递时,调用str.join将加入列名,就像一样

'|'.join(df)
# 'group|sc|wc'  # this joins on the column names because iteration 
# on dataFrames devolves to iteration over headers

请注意,将aggapply与非细胞化(或者至少没有快速路径(的函数一起使用几乎没有区别。

最新更新