考虑以下代码。此代码的目的是遍历groupby
,并将来自组中每行的信息合并并保存到pd.Series
中。
import numpy as np
df = pd.DataFrame({"A" : ["a", "a", "b", "b", "a"], "B" : ["x", "y", "z", "w", "t"] })
groups = df.groupby("A")
strings = groups["B"].apply(lambda x : "".join(sorted(x.values + " ")))
strings2 = groups["B"].apply(lambda x : str(len(np.unique(x))) + "hello")
print(strings)
print(strings2)
字符串
输出
a t x y
b w z
Name: B, dtype: object
A
a 3hello
b 2hello
Name: B, dtype: object
型
例如,上面代码示例中的第一个apply语句是将"B"
列的行连接成一个字符串,并添加空格。
我想使这段代码尽可能快,并能够缩放到数百万行的设置。
这是目前为止我能找到的最有效的方法来完成这项任务,但我认为部分问题在于.apply
在pandas中没有矢量化,所以将其应用到每个组是一个非常缓慢的过程(通常,有超过30万组)。每个组只有大小2或3。
或者,我可以尝试跳过groupby
,直接在原来的DataFrame
上这样做。也将赞赏以这种方式工作的解决方案。
总之,我希望有一种方法来重写上面的代码,实现相同的事情,但尽可能快和空间效率(可扩展到超大数据集)。
3条答案
按热度按时间jyztefdp1#
我找到的
strings2
的最快解决方案是:字符串
对于
strings2
,OP的方法非常慢:型
的数据
因此,我将其排除在大样本上运行:
的
对于
strings
,我惊讶地发现:我可以通过使用原生
pd.Series.str.join
来改进OP的解决方案,而不是使用纯Python的连接:的字符串
的
的
使用的分析代码:
型
ehxuflar2#
我尝试的第一个方法的其他实现,包括Andrej建议的,都比你的要差。除非是一个排序网络,否则无论规模大小,排序都是非常昂贵的。
UPD
阅读Sebastian's惊人的答案让我陷入了优化的兔子洞。我们真的能做得更好吗?显然,我们可以:Python lists: why is .sort() much faster than sorted()?的
型
100d1x
的字符串
wixjitnu3#
IIUC,你可以在分组之前按列
B
对 Dataframe 进行排序,然后只应用str.join
:字符串
印刷品:
型