【问题标题】:FIlter data based on month and ID and sum in Pandas在 Pandas 中根据月份和 ID 和总和过滤数据
【发布时间】:2020-06-23 08:02:54
【问题描述】:

ID. Email. Amount Date 1. wi@gn.c. 20 26-11-19 12.06.36.726000 2. wi@gn.c. 40 26-12-19 12.06.37.293000 3. by@gn.c. 50 26-11-19 12.06.37.960000 4. wi@gn.c. 20 26-01-20 12.06.51.306000 5. wi@gn.c. 60 26-02-20 12.06.52.458000 6. by@gn.c. 15 26-08-19 12.06.58.397000 7. wi@gn.c. 37 26-12-19 12.07.00.191000 5. wi@gn.c. 60 26-02-20 12.06.52.458000 6. by@gn.c. 15 26-08-19 12.06.58.397000 7. wi@gn.c. 37 26-12-19 12.07.00.191000

我需要获取每个电子邮件地址在过去 1 个月、3 个月和 6 个月的总金额。我已经尝试了几种命令组合,但现在我迷路了。

在另一个答案df.groupby('Email')['Amount'].sum().reset_index() 有效,但我需要根据 1 个月、3 个月和 6 个月添加总和。

预期的结果将如下所示

ID. Email. Total for past 1 Month Total for past 3 Month Total for past 6 Month 1. wi@gn.c. 20 40 60 3. by@gn.c. 50 50 100

注意:最终的数字并不完全正确,我只是想描绘一下我正在尝试做的事情。

【问题讨论】:

  • 我猜你可以使用数据透视表
  • @davidbilla,感谢您的建议,我会阅读它并了解情况如何,但我对 python 比较陌生,我是一名需要对某些数据进行一些操作的 java 开发人员在python中
  • 我建议从其中一列开始,然后使用 df[df[date column]>= x months ago].groupby ...
  • @WinfredAdrah 请在下面查看我的回答。对此可能有更有效的解决方案。
  • @davidbilla,我在 excel 中手动进行了计算,但与您的结果不符

标签: python pandas datetime filter jupyter-notebook


【解决方案1】:

希望这会有所帮助:首先将您的“日期”列转换为 DateTimeIndex。然后你必须将你的数据分成 1 个月、3 个月和 6 个月的组并创建 3 个 dfs。按“金额”之和聚合这 3 个 dfs。最后,将所有这 3 个 dfs 合并到“电子邮件”列。

import numpy as np
import pandas as pd

df = pd.DataFrame([[1,'wi@gn.c.',20,'26-11-19 12.06.36.726000'],
                   [2,'wi@gn.c.',40,'26-12-19 12.06.37.293000'],
                   [3,'by@gn.c.',50,'26-11-19 12.06.37.960000'],
                   [4,'wi@gn.c.',20,'26-01-20 12.06.51.306000'],
                   [5,'wi@gn.c.',60,'26-02-20 12.06.52.458000'],
                   [6,'by@gn.c.',15,'26-08-19 12.06.58.397000'],
                   [7,'wi@gn.c.',37,'26-12-19 12.07.00.191000'],
                   [6,'wi@gn.c.',60,'26-02-20 12.06.52.458000'],
                   [7,'by@gn.c.',15,'26-08-19 12.06.58.397000'],
                   [8,'wi@gn.c.',37,'26-12-19 12.07.00.191000']],
                  columns=['ID','Email','Amount','Date'])

# convert your 'Date' to datetimeindex
df['Date'] = pd.to_datetime(df['Date'], format = '%d-%m-%y %H.%M.%S.%f')
df.set_index('Date', inplace=True)
df.sort_index(inplace=True)

# create dfs from base df for past 1 month, 3 months and 6 months data and aggregate by sum of 'Amount'
end = pd.datetime.now()
df_1mo = df.loc[end - pd.DateOffset(months=1): end].groupby('Email')['Amount'].agg(total_1mo=np.sum)
df_3mo = df.loc[end - pd.DateOffset(months=3): end].groupby('Email')['Amount'].agg(total_3mo=np.sum)
df_6mo = df.loc[end - pd.DateOffset(months=6): end].groupby('Email')['Amount'].agg(total_6mo=np.sum)

# merge all 3 dfs on 'Email'
print(df_1mo.merge(df_3mo, on='Email', how='outer').merge(df_6mo, on='Email', how='outer').fillna(0))

输出:

          total_1mo  total_3mo  total_6mo
Email                                    
wi@gn.c.      120.0      254.0        274
by@gn.c.        0.0        0.0         50
  • 在过去 1 个月的范围内(2 月 11 日至 3 月 11 日),您只有 2 行 Date 为 02/26,均与 Email wi@gn.c。和Amount 的总和 是 60+60=120。
  • 在过去 3 个月的范围内(12 月 11 日至 3 月 11 日),您有 6 Date 为 02/26/2020、01/26/2020 和 12/26/2019 的行都带有 相同的Email wi@gn.c。 Amount 的总和是 60+60+20+37+37+40=254。
  • 在过去 6 个月的范围内(9 月 11 日至 3 月 11 日),您 有 8 行,Date 为 02/26/2020、01/26/2020、12/26/2020 和 2019 年 11 月 26 日。这一行是Email by@gn.c。和Amount 为50。所有其他行都带有Email wi@gn.c。 Amount 的和是 60+60+20+37+37+40+20=274。
  • 其他 2 行以 Date 为 2020 年 8 月 26 日不在这个 6 个月的范围内,因此它们被排除在外。

希望这可以解释答案。您可以将end 日期更改为不同的日期以作为基准日期。这里我使用当前日期作为基准日期。

对此可能有更有效的解决方案。但这应该基于您的示例数据集。告诉我进展如何。

更新:最小值和最大值:

df_1mo = df.loc[end - pd.DateOffset(months=1): end].groupby('Email')['Amount'].agg(total_1mo=np.max)
df_3mo = df.loc[end - pd.DateOffset(months=3): end].groupby('Email')['Amount'].agg(total_3mo=np.max)
df_6mo = df.loc[end - pd.DateOffset(months=6): end].groupby('Email')['Amount'].agg(total_6mo=np.max)

# merge all 3 dfs on 'Email'
print(df_1mo.merge(df_3mo, on='Email', how='outer').merge(df_6mo, on='Email', how='outer').fillna(0))

输出:

          total_1mo  total_3mo  total_6mo
Email                                    
wi@gn.c.       60.0       60.0         60
by@gn.c.        0.0        0.0         50

【讨论】:

  • 感谢@davidbilla 的更新,但我收到错误index must be monotonic increasing or decreasing 我正在查找是否能找到解决方案,但如果您有解决方案,我将不胜感激.谢谢
  • 在切片之前,您必须使用df.sort_index(inplace=True) 对 df 进行排序。检查更新的解决方案。
  • 非常感谢,我真的很感激。
  • @WinfredAdrah 很高兴我能帮上忙!!
  • 对不起,我必须回来,但我需要获得同一时期的最小和最大数量,我已经尝试过 np.max 并按 min() 分组。但我不太确定。请让我知道这是否应该是一个单独的问题
猜你喜欢
  • 2021-11-25
  • 2018-11-23
  • 2021-11-01
  • 2014-03-15
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多