python - pandas groupby + apply 的快速替代方案?
问题描述
我有一个 pandas 数据框,如下所示(大约 100 万行):
Column_1 Column_2 Column_3 Column_4 Column_5 Column_6 Column_7 Column_8 Column_9 Column_10
… … … … … … … … … …
… … … … … … … … … …
… … … … … … … … … …
… … … … … … … … … …
我想要做:
grouping = ["Column_1", "Column_2", "Column_3", "Column_4"]
df.groupby(grouping).apply(lambda x: pd.Series({
'new_column_1':func_1(x),
'new_column_2':func_2(x),
'new_column_3':func_3(x)}
)).reset_index()
这有效,但速度非常慢。函数 [func_1, func_2, func_3] 是我想应用于每个组的自定义函数。
我阅读了其他关于为什么这么慢的堆栈溢出讨论。我发现的原因是 pandas groupby + apply 使用 python 循环而不是矢量化。但那我怎么能加快速度呢?
例如,假设:
def func_1(x) {
return sum(x["Column_5"] >= x["Column_6"]) / sum(x["Column_5"] <= x["Column_6"])
}
def func_2(x) {
return max(x["Column_8"]) + min(x["Column_9"])
}
def func_3(x) {
return len(x)
}
如果没有 pandas groupby + numpy,我们怎么能做同样的操作?
解决方案
看起来您想比较每行中 2 个不同列的值,然后逐行计算比较的结果,然后对计数进行数学运算。如果是这样,请创建 2 个具有比较结果的新列,然后对这些新列求和并比较数字。矢量化而不是迭代。看这个玩具例子:
row1list = [1, 2]
row2list = [5, 3]
row3list = [5, 4]
row4list = [5, 5]
df = pd.DataFrame([row1list, row2list, row3list, row4list],
columns=['Column_5', 'Column_6'])
df[['col5 >= col6', 'col6 <= col5']] = 0, 0
# start with 0, else you get nan or 1 in the next comparison
df.loc[df['Column_5'] >= df['Column_6'], 'col5 >= col6'] = 1
df.loc[df['Column_5'] <= df['Column_6'], 'col6 <= col5'] = 1
print(df)
# Column_5 Column_6 col5 >= col6 col6 <= col5
# 0 1 2 0 1
# 1 5 3 1 0
# 2 5 4 1 0
# 3 5 5 1 1
answer_of_func1 = sum(df['col5 >= col6']) / sum(df['col6 <= col5'])
print(answer_of_func1)
# 1.5
推荐阅读
- django - Django - DRF (django-rest-framework-social-oauth2) 和 React 创建用户
- javascript - Underscore.js + Visual Studio Code = Uncaught SyntaxError: Unexpected token {
- php - 数据表服务器端实现
- macos - 如何用 libpng 写一个 16 位的 PNG_COLOR_TYPE_GRAY?
- apache-spark - 第一次运行 Spark、PySpark
- react-redux - 如何在 redux-saga 中测试异步 axios 请求?
- python - Python:查找所有用元音代替星号的单词
- javascript - Javascript 错误:JupyterLab 中未定义 IPython
- javascript - 使用 nodejs 验证文件上传
- javascript - Javascript 对象 - 过滤时,我的对象的键成为有序数字列表