用另一个df中的值替换df中的值

时间:2019-08-15 16:09:51

标签: pandas dictionary replace lookup

我有一个数据表df1,看起来像这样(df.groupby('id').agg(lambda x: x.tolist())的结果):

df1:

id   people     
51   [125, 126, 127, 128, 129]
52   [302, 303, 128]
53   [312]

在另一个数据帧df2中,我根据唯一的pid映射了姓名和性别。 df1.people中的列表条目实际上就是那些pid项:

df2:

pid    name           gender
100    Jack Lumber    m
125    Holly Polly    f
126    Jeremy Owens   m
127    Ron Bronco     m
128    Natalia Berg   f
129    Robyn Hill     f
300    Crusty Clown   m
302    Danny McKenny  m
303    Tara Hill      f
312    Glenn Dalough  m
400    Fryda Beans    f

现在,我想用gender中的df2字段替换或映射各个pid,从而创建以下所需的输出,包括列表计数:

Outcome:
id   gender            count_m  count_f  
51   [f, m, m, f, f]   2        3
52   [m, f, f]         1        2
52   [m]               1        0

创建此表的最佳方法是什么?

解决方案:

from collections import Counter
d = dict(df2.drop('name', 1).values)
m = df1.assign(gender=df1.name.apply(lambda x: [d.get(i) for i in x])).drop('people', 1)
n = pd.DataFrame([Counter(x) for x in m.gender], index=m.index).fillna(0).add_prefix('count_')
final = m.join(n)

1 个答案:

答案 0 :(得分:1)

您可以使用dict.get()获取相应的字典值,然后通过展开数据框并应用crosstab然后合并来创建数据框:

d=dict(df2.drop('name',1).values)
m=df1.assign(gender=df1.people.apply(lambda x: [d.get(i) for i in x])).drop('people',1)
n=pd.DataFrame({'id':m.loc[m.index.repeat(m.gender.str.len()),'id'],
'gender':np.concatenate(m.gender)})
#for pandas .25.0 use: n=m.explode('gender')

final=m.merge(pd.crosstab(n.id,n.gender).add_prefix('count_'),left_on='id',right_index=True)

   id           gender  count_f  count_m
0  51  [f, m, m, f, f]        3        2
1  52        [m, f, f]        2        1
2  53              [m]        0        1