【问题标题】:How to optimize large pandas dataframe which is using groupby and aggregation?如何优化使用 groupby 和聚合的大熊猫数据框?
【发布时间】:2020-05-22 11:21:48
【问题描述】:

我正在读取一个包含大约 300k 行的 excel 文件到 pandas 数据框。我是, 然后,使用 groupby 将其分组到大约 18000 行。然后,我循环每个组并计算组中的过滤器(月份数据的日期过滤器)的总和。整个过程大约需要60分钟。有没有办法优化这个?代码如下:

    qgift_dl = pd.read_csv(file, encoding='latin1')
    qgift_dl['user_id'] = df1['user_id'].astype(str)  # read csv file
    qgift_dl['Gift Date'] = pd.to_datetime(df1['Gift Date'])
    min_date = qgift_dl['Gift Date'].min()
    today = datetime.datetime.today()
    qgift_dates = get_date_range(min_date, today) # get all dates between
    q_grouped = qgift_dl.groupby(['user_id'])
    details= []
    for group in q_grouped:
        d_rows = group[1]
        d_row_data = [group[0]]  # add donor id
        for dt in qgift_dates:
            lower = dt.strftime('%Y-%m-01')
            upper = dt.strftime('%Y-%m-%d')
            filtered = d_rows[(d_rows['Gift Date'] >= lower) & (d_rows['Gift Date'] <= upper)]
            d_row_data.append(filtered['Amount'].sum())
        details.append(d_row_data)

下面是get_date_range函数。它获取两个范围之间的所有日期(Y-m-d)的范围。在我的情况下,范围是“2008-04-30”到“2020-05-30”。

from dateutil.relativedelta import relativedelta
import datetime, calendar

def get_date_range(start, end):

    result = []
    while start <= end:
        result.append(start)
        start += relativedelta(months=1)
    return result

Excel 数据示例如下: 示例文件链接: https://docs.google.com/spreadsheets/d/1YeH35w0rqVoHukGTSDtISlztdZAiDYsmfLWVia2x1U0/edit?usp=sharing

【问题讨论】:

  • 您能提供一些示例数据吗? get_date_range 是什么?我们如何尝试复制?
  • 我已经用示例数据和 get_date_range def 更新了问题。原始数据在 300k 左右。谢谢
  • 我仍然无法从 png 文件中复制粘贴...您说您获得了所有日期,但 get_date_range 添加(或多或少...)月份。如果没有一些可复制的数据和预期的结果,我无法为您提供帮助。
  • @user3929745 你介意解释一下这里应该是什么下部和上部吗?如果您也可以添加预期的输出,那就太好了。
  • 在我看来,您正在查找从该组的任何元素中从月初至今的累计捐款金额。我错了吗?

标签: python pandas optimization


【解决方案1】:

根据预期结果,您需要每个用户和每个月的总金额。熊猫工具是groupbysum,如果您希望日期成为列,则unstack

result = df.groupby(['user_id', pd.to_datetime(df['Gift Date'], dayfirst=True
                    )+ pd.offsets.Day() - pd.offsets.MonthBegin()])[['Amount']].sum(
             ).unstack()

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 2021-03-21
    • 2023-02-25
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多