慢循环汇总行和列

时间:2018-11-26 05:38:37

标签: python-3.x pandas

我有一个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进行汇总)。

1 个答案:

答案 0 :(得分:0)

我撤回了这个问题。

我曾希望有一种将groupby与其他方式结合使用的有效方法,但是我还没有找到具有这种复杂数据结构的示例,因此没有得到指导。

对于同样在Python中遇到非常慢的聚合问题的人,我建议加紧PySpark。我现在使用Databricks笔记本解决此问题,并通过pyspark.sql.window窗口函数取得进展。 (现在,只需几分钟即可运行测试,而不是几个小时!)

这里的答案是部分解决方案:

PySpark list() in withColumn() only works once, then AssertionError: col should be Column