组合Pandas中的两个数据帧以生成多对多关系

组合Pandas中的两个数据帧以生成多对多关系,pandas,dataframe,random,many-to-many,associations,Pandas,Dataframe,Random,Many To Many,Associations,比如说,我有两份清单 customers = ['a', 'b', 'c'] accounts = [1, 2, 3, 4, 5, 6, 7, 8, 9] 我想生成一个数据帧,以便: 使用所有客户和帐户 客户和账户之间存在多对多关系(一个客户“可能”拥有多个账户,而一个账户“可能”拥有多个客户) 我希望多对多关系是随机的。也就是说,一些客户将拥有一个帐户,而一些客户将拥有多个帐户。类似地,一些帐户将仅由一个客户拥有,而其他帐户将由多个客户拥有 大概 顾客 账户 A. 1. A. 2. B 2.

比如说,我有两份清单

customers = ['a', 'b', 'c']
accounts = [1, 2, 3, 4, 5, 6, 7, 8, 9]
我想生成一个数据帧,以便:

  • 使用所有客户和帐户
  • 客户和账户之间存在多对多关系(一个客户“可能”拥有多个账户,而一个账户“可能”拥有多个客户)
  • 我希望多对多关系是随机的。也就是说,一些客户将拥有一个帐户,而一些客户将拥有多个帐户。类似地,一些帐户将仅由一个客户拥有,而其他帐户将由多个客户拥有
  • 大概

    顾客 账户 A. 1. A. 2. B 2. C 3. A. 4. B 4. C 4. B 5. B 6. B 7. B 8. A. 9
    实现这一点的一种方法是收集笛卡尔乘积的所有可能关系集,然后在构建数据帧之前从该列表中选择:

    import itertools
    import random
    
    customers = ['a', 'b', 'c']
    accounts = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    possible_associations = [ca for ca in itertools.product(customers, accounts)]
    df = pd.DataFrame.from_records(random.choices(possible_associations, k=20), columns=['customers', 'accounts']).sort_values(['customers','accounts'])
    print(df)
    
    输出
    要获得可重复的测试结果,请从目标中的np.random.seed(1)开始 版本(请放下它)

    然后进行如下操作:

  • 创建概率列表-一个客户可以拥有多少个帐户,例如:

    prob = [0.5, 0.25, 0.15, 0.09, 0.01]
    
  • 生成一个系列,说明每个帐户应有多少所有者:

    cnt = pd.Series(np.random.choice(range(1, len(prob) + 1), size=len(accounts),
        p=prob), name='Customer')
    
    它的名字是Customer,因为它将是刚刚创建的源 客户栏

    对于我的样本概率和发电机播种,结果是:

    0    1
    1    2
    2    1
    3    1
    4    1
    5    1
    6    1
    7    1
    8    1
    Name: Customer, dtype: int32
    
    (左栏为索引,右栏为实际值)

    因为您的数据样本只包含9个帐户,所以结果不会 不包含“更多”的所有者。但在目标版本中, 有了更多的账户,就会有更多的客户 所有者

  • 生成结果-cust_acct数据框,定义客户分配 对账户:

    cust_acct = cnt.apply(lambda x: np.random.choice(customers, x, replace=False))\
        .explode().to_frame().join(pd.Series(accounts, name='Account')).reset_index(drop=True)
    
  • 对于您的样本数据以及我的种子和概率,结果是:

      Customer  Account
    0        b        1
    1        a        2
    2        b        2
    3        b        3
    4        b        4
    5        c        5
    6        b        6
    7        c        7
    8        a        8
    9        b        9
    
    当然,你可以在prob中假设不同的proability。 您还可以选择其他“顶级”所有者数量( prob中的条目)。 在这种情况下,不需要更改代码,因为 第一个np.random.choice设置为与prob的长度相适应

    注意:因为您的样本数据只包含3个客户, 在不同的生成器种子设定下,可能会发生ValueError:Cannot 当“replace=False”时,采取比总体更大的样本

    原因是,如果某个帐户的所有者数量大于3,则 发生此错误

    但对于您的目标数据,对于更多的客户,这一错误
    不会发生。

    什么是最好的方法…是基于意见的问题。因此不是编码服务。请阅读以下文档,然后重新表述问题。&。始终提供代码、数据、错误、当前输出和预期输出,正如您所期望的那样。我认为,但笛卡尔积将匹配eve我希望有些客户有一个帐户,有些客户有多个帐户。同样,我希望有些客户有一个客户,有些客户有多个帐户。基本上,我希望创建一个随机多对多关联。谢谢你的澄清。我更新了我的答案,让rando这更像是你想要实现的吗?
      Customer  Account
    0        b        1
    1        a        2
    2        b        2
    3        b        3
    4        b        4
    5        c        5
    6        b        6
    7        c        7
    8        a        8
    9        b        9