python-3.x - 聚合行和列的慢循环
问题描述
我有一个 DataFrame,其中有一列名为“UserNbr”,一列名为“Spclty”,它由以下元素组成:
[['104', '2010-01-31'], ['215', '2014-11-21'], ['352', '2016-07-13']]
列表中可以有 0 个或多个元素。
一些 UserNbr 键出现在多行中,我希望将每个这样的组折叠成一行,以便“Spclty”包含所有唯一的字典,就像上面显示的列表中的字典一样。
为了节省附加到 DataFrame 的开销,我将每个输出行附加到一个列表,而不是附加到 DataFrame。
我的代码正在运行,但在 0.7M 行输入上运行需要数小时。(实际上,我从来没有让我的笔记本电脑打开足够长的时间让它完成执行。)
有没有更好的方法来聚合成这样的结构,也许使用提供更多数据重塑选项的库而不是循环遍历 UserNbr?(在 R 中,我会使用 data.table 和 dplyr 库。)
# loop over all UserNbr:
# consolidate specialty fields into dict-like sets (to remove redundant codes);
# output one row per user to new data frame
out_rows = list()
spcltycol = df_tmp.column.get_loc('Spclty')
all_UserNbr = df_tmp['UserNbr'].unique()
for user in all_UserNbr:
df_user = df_tmp.loc[df_tmp['UserNbr'] == user]
if df_user.shape[0] > 0:
open_combined = df_user_open.iloc[0, spcltycol] # capture 1st row
for row in range(1, df_user.shape[0]): # union with any subsequent rows
open_combined = open_combined.union(df_user.iloc[row, spcltycol])
new_row = df_user.drop(['Spclty', 'StartDt'], axis = 1).iloc[0].tolist()
new_row.append(open_combined)
out_rows.append(new_row)
# construct new dataframe with no redundant UserID rows:
df_out = pd.DataFrame(out_rows,
columns = ['UserNbr', 'Spclty'])
# convert Spclty sets to dicts:
df_out['Spclty'] = [dict(df_out['Spclty'][row]) for row in range(df_out.shape[0])]
到 dict 的转换消除了行之间重复的特性,在输出中,Spclty 值应如下所示:
{'104': '2010-01-31', '215': '2014-11-21', '352': '2016-07-13'}
除了可能存在比任何相应输入行中更多的键值对(由对 UserNbr 的聚合产生)。
解决方案
我撤回这个问题。
我曾希望有一种有效的方法将 groupby 与其他东西一起使用,但我还没有找到任何具有像这样的复杂数据结构的示例,也没有得到任何指导。
对于那些在 Python 中遇到类似的非常缓慢的聚合问题的人,我建议加紧使用 PySpark。我现在正在使用 Databricks 笔记本解决这个问题,并且正在使用 pyspark.sql.window Window 函数取得进展。(现在,运行测试只需几分钟而不是几小时!)
部分解决方案在此处的答案中:
PySpark list() in withColumn() 只工作一次,那么 AssertionError: col 应该是 Column
推荐阅读
- javascript - Firestore 以秒和纳秒为单位保存时间戳
- css - 使用 JS 的进度动画
- web-scraping - scrapy + splash 响应不完整的页面
- c - 非规范模式不适用于反引号
- combinations - 从两个数组中找到元素的最佳组合,总共五个元素
- c# - 并行化如何在 async/await 上工作?
- c++ - 来自浏览器套接字的函数recv,但在缓冲区中不存储任何内容
- android - 如何使我的代码的一部分可供多个活动访问
- asp.net-mvc - 当验证在服务器端并在页面加载时使用数据注释时如何隐藏警报框
- vis.js - Vis js时间线范围元素自定义绘制