我有两个数据框。第一个与用户有关,看起来像这样:
user_id city_id
0 a
1 a
2 b
3 a
4 c
.. and so on
第二个信息提供了每个城市属于每个地区的百分比,如下所示:
city_id district_id probability
a a1 0.01
a a2 0.02
a a3 0.02
a a4 0.56
a a5 0.39
b b1 0.63
b b2 0.07
b b3 0.30
and so on..
我需要根据这种可能性来组织用户,他们属于他们所在城市的地区。因此(例如)我大约有56%的人居住在城市a中,他们来自a4区,依此类推。基本上,最终df将具有与的相关行user_id, city_id and district_id
。
我的第一个提示是给每个用户一个随机数,并与概率进行比较。
我的第二个想法是按city_id对行进行分组,以查看第二个表并按概率选择(将值赋予第三列)。所以基本上对于城市a,这意味着我将在组中选择56%的行,并将其区域值赋予a4,依此类推。但是我不确定数学上是不是最好的方法。
如果df1
和df2
是您的两个数据框:
import numpy as np
def get_district(city):
dlist = list(df2.loc[df2['city_id']==city, 'district_id']) #get list of districts
p = list(df2.loc[df2['city_id']==city, 'probability']) #get corresponding odds
return np.random.choice(dlist, p=p) #give weighed random choice from list
并应用此:
df['district_id'] = df.city_id.apply(get_district)
在@JoeCondron的有用评论之后,另一种方法是:
def get_city_district(city,df1,df2):
l = len(df1[df1.city_id==city])
d = df2[df2['city_id']==city]
ds, p = list(d['district_id']),list(d['probability'])
df1.loc[df1.city_id==city,'district_id'] = np.random.choice(ds, size=l,p=p)
return df1
def f(df1,df2):
df1['district_id'] = None
for i in set(df1.city_id):
df1 = get_city_district(i,df1,df2)
return df1
经过测试的速度要快得多,但仅限少数几个城市。
这将要求
get_district
每一行,df
而每一行又将df2
不必要地进行切片。我们只需要获取每个唯一城市的权重一次。此外,您将两次生成相同的布尔键。