查找 pandas 中每月某个时间范围内发生的定期付款

问题描述 投票:0回答:2

我有一个数据框,我想找到同一 ID 的定期付款(仅当金额相同且当月日期相同且有误差范围(+-5 天)时)。 我做了以下事情:

d = {'id':[1,1,1,3,3,3,5,5,5],
    'day_of_month':[2,2,5,4,6,8,10,15,25],
    'amount':[1000,1000,50,1500,3000,1500,4000,2000,2000]}
dd = pd.DataFrame(d)
print(dd)
    id  day_of_month    amount
0   1     2            1000
1   1     2            1000
2   1     5             50
3   3     4            1500
4   3     6            3000
5   3     8            1500
6   5     10           4000
7   5     15           2000
8   5     25           2000

然后我这样做:

dd[dd.duplicated(subset = ['id','amount'], keep = False)]
    id  day_of_month       amount
0   1      2                1000
1   1      2                1000
3   3      4                1500
5   3      8                1500
7   5      15               2000
8   5      25               2000

正如您所看到的,输出的最后一行是误报,因为我还没有设法实现当月的 +-5 天窗口。 我想要的输出应该是这样的

   id       day_of_month    amount
0   1      2                1000
1   1      2                1000
3   3      4                1500
5   3      8                1500

关于如何实现我需要的有什么想法吗?谢谢!

python python-3.x pandas dataframe duplicates
2个回答
1
投票

为什么不添加另一个

mask

您的原创

mask

non_duplicates_mask = dd.duplicated(subset = ['id','amount'], keep = False)

月份

mask
:

months_mask = abs(dd['day_of_month'] - dd['day_of_month'].shift()) >= 5

我使用

abs
只是为了防止
day_of_month
并不总是按升序排列,

然后对两个蒙版进行

xor
操作:

dd[non_duplicates_mask ^ months_mask]

输出:

    id  day_of_month    amount
0   1   2               1000
1   1   2               1000
3   3   4               1500
5   3   8               1500

编辑:

xor
(异或)的运作方式如下: enter image description here


0
投票

为您提供很大灵活性的另一种选择是使用带有聚合的 groupby。

d = {'id':[1,1,1,3,3,3,5,5,5],
    'day_of_month':[2,2,5,4,6,8,10,15,25],
    'amount':[1000,1000,50,1500,3000,1500,4000,2000,2000]}
dd = pd.DataFrame(d)
someDF = dd.groupby(by=['id','amount'])\
              .agg({"day_of_month":['median', 'std', 'count']}).reset_index(drop=False)
# filter on those with duplicates
someDF = someDF[someDF[("day_of_month", "count")] > 1]

现在您可以使用任意数量的统计方法来确定该月的某一天是否“足够接近”。

  id amount          day_of_month                
                  median       std count
1  1   1000          2.0  0.000000     2
2  3   1500          6.0  2.828427     2
4  5   2000         20.0  7.071068     2

您当前的过滤器表明标准差小于 3 就构成“足够接近”。 对于较大的数据集(其中有很多重复项,通常分布在平均值周围),您可以使用变换函数将其与组平均值的距离或 PDF 计算写回每个记录,然后基于此进行过滤。

© www.soinside.com 2019 - 2024. All rights reserved.