我还是个新手,我正在努力解决将一些随机ID分配给"相关"行的问题 其中关系简单地是他们在按用户分组的连续几天中的接近程度(在14天内).在那个例子中,我 Select 了uuid,没有任何特别的意图.它可以是唯一标识概念上相关行的任何其他随机ID.

        import pandas as pd
        import uuid
        import numpy as np

以下是一个虚拟数据帧:

        dummy_df = pd.DataFrame({"transactionid": [1, 2, 3, 4, 5, 6, 7, 8],
                                "user": ["michael", 
                                                    "michael", 
                                                    "michael", 
                                                    "tom", 
                                                    "tom", 
                                                    "tom",
                                                    "tom", 
                                                    "tom"],
                                "transactiontime": pd.to_datetime(["2022-01-01", 
                                                                "2022-01-02", 
                                                                "2022-01-03", 
                                                                "2022-09-01", 
                                                                "2022-09-13",
                                                                "2022-10-17",
                                                                "2022-10-20",
                                                                "2022-11-17"])})
        dummy_df.head(10)
        
        transactionid   user    transactiontime
                0   1   michael 2022-01-01
                1   2   michael 2022-01-02
                2   3   michael 2022-01-03
                3   4   tom     2022-09-01
                4   5   tom     2022-09-13
                5   6   tom     2022-10-17
                6   7   tom     2022-10-20
                7   8   tom     2022-11-17

我在这里对交易进行排序,并计算它们之间的差额(以天为单位):

        dummy_df = dummy_df.assign(
            timediff = dummy_df
            .sort_values('transactiontime')
            .groupby(["user"])['transactiontime'].diff() / np.timedelta64(1, 'D')
            ).fillna(0)
        
        dummy_df.head(10)
        
        
        transactionid   user    transactiontime timediff
                0   1   michael 2022-01-01  0.0
                1   2   michael 2022-01-02  1.0
                2   3   michael 2022-01-03  1.0
                3   4   tom     2022-09-01  0.0
                4   5   tom     2022-09-13  12.0
                5   6   tom     2022-10-17  34.0
                6   7   tom     2022-10-20  3.0
                7   8   tom     2022-11-17  28.0

在这里,我 for each 相关事务创建了一个具有随机ID的新列--尽管它并不像预期的那样工作:

        dummy_df.assign(related_transaction = np.where((dummy_df.timediff >= 0) & (dummy_df.timediff < 15), uuid.uuid4(), dummy_df.transactionid))
        
        
        transactionid   user    transactiontime timediff    related_transaction
                0   1   michael 2022-01-01  0.0  fd630f07-6564-4773-aff9-44ecb1e4211d
                1   2   michael 2022-01-02  1.0  fd630f07-6564-4773-aff9-44ecb1e4211d
                2   3   michael 2022-01-03  1.0  fd630f07-6564-4773-aff9-44ecb1e4211d
                3   4   tom     2022-09-01  0.0  fd630f07-6564-4773-aff9-44ecb1e4211d
                4   5   tom     2022-09-13  12.0 fd630f07-6564-4773-aff9-44ecb1e4211d
                5   6   tom     2022-10-17  34.0    6
                6   7   tom     2022-10-20  3.0  fd630f07-6564-4773-aff9-44ecb1e4211d
                7   8   tom     2022-11-17  28.0    8

假设交易之间的用户组差异在14天内,我希望是这样的:

        transactionid   user    transactiontime timediff    related_transaction
                0   1   michael 2022-01-01  0.0  ad2a8f23-05a5-49b1-b45e-cbf3f0ba23ff
                1   2   michael 2022-01-02  1.0  ad2a8f23-05a5-49b1-b45e-cbf3f0ba23ff
                2   3   michael 2022-01-03  1.0  ad2a8f23-05a5-49b1-b45e-cbf3f0ba23ff
                3   4   tom     2022-09-01  0.0  b1da2251-7770-4756-8863-c82f90657542
                4   5   tom     2022-09-13  12.0 b1da2251-7770-4756-8863-c82f90657542
                5   6   tom     2022-10-17  34.0 485a8d97-80d1-4184-8fc8-99523f471527
                6   7   tom     2022-10-20  3.0  485a8d97-80d1-4184-8fc8-99523f471527
                7   8   tom     2022-11-17  28.0    8

推荐答案

借鉴路易丝的 idea ,我们从related_transaction英镑的空栏开始.然后,我们遍历每一行.对于每个日期,我们判断它是否已经是交易的一部分.如果是,请继续.否则,为同一用户在以下15天内将新交易记录分配给该日期和所有其他日期:

import datetime
df = dummy_df
df['related_transaction'] = None
for i, row in dummy_df.iterrows():
    if df.loc[i].related_transaction is not None:
        # We already assigned that row
        continue
    df.loc[  # Select where:
        (df.transactiontime <= row.transactiontime + datetime.timedelta(days=15)) & #  Current row + 15 days
        (df.user == row.user) &  # Same user
        (pd.isna(df.related_transaction)),  # Don't overwrite anything already assigned
        'related_transaction'  #  Set this column to:
    ] = uuid.uuid4()  # Assign new UUID

这将提供以下输出:


    transactionid   user    transactiontime related_transaction
0               1   michael 2022-01-01      82d28e10-149b-481e-ba41-f5833662ba99
1               2   michael 2022-01-02      82d28e10-149b-481e-ba41-f5833662ba99
2               3   michael 2022-01-03      82d28e10-149b-481e-ba41-f5833662ba99
3               4   tom     2022-09-01      fa253663-8615-419a-afda-7646906024f0
4               5   tom     2022-09-13      fa253663-8615-419a-afda-7646906024f0
5               6   tom     2022-10-17      d6152d4b-1560-40e0-8589-bd8e3da363db
6               7   tom     2022-10-20      d6152d4b-1560-40e0-8589-bd8e3da363db
7               8   tom     2022-11-17      2a93d78d-b6f6-4f0f-bb09-1bc18361aa21

在您的示例中,日期已经排序,这是我在这里做出的一个重要假设!

Python相关问答推荐

我可以使用极点优化这个面向cpu的pandas代码吗?

如何才能将每个组比上一组增加N %?

Pandas 在时间序列中设定频率

配置Sweetviz以分析对象类型列,而无需转换

pandas DataFrame GroupBy.diff函数的意外输出

Pytest两个具有无限循环和await命令的Deliverc函数

使用miniconda创建环境的问题

如何让程序打印新段落上的每一行?

基于字符串匹配条件合并两个帧

如何使用表达式将字符串解压缩到Polars DataFrame中的多个列中?

将9个3x3矩阵按特定顺序排列成9x9矩阵

如何在Polars中从列表中的所有 struct 中 Select 字段?

使用Python更新字典中的值

字符串合并语法在哪里记录

如何在达到end_time时自动将状态字段从1更改为0

如何在BeautifulSoup/CSS Select 器中处理regex?

在不同的帧B中判断帧A中的子字符串,每个帧的大小不同

使用字典或列表的值组合

30个非DATETIME天内的累计金额

在用于Python的Bokeh包中设置按钮的样式