组合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]
我想生成一个数据帧,以便:
实现这一点的一种方法是收集笛卡尔乘积的所有可能关系集,然后在构建数据帧之前从该列表中选择:
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 = 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