【问题标题】:Replacing values in a df with values from another df用另一个df中的值替换df中的值
【发布时间】:2019-12-22 01:48:25
【问题描述】:

我有一个数据表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

现在我想用来自df2gender 字段替换或映射相应的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)

【问题讨论】:

  • 熊猫'0.24.2'

标签: pandas dictionary replace lookup


【解决方案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

【讨论】:

  • 谢谢,非常接近!唯一剩下的问题:计数似乎无法正常工作。例如:如果我有一个像 [female, female, male, female, female] 这样的序列,它在两个字段中都计数为 1, 1。我认为它在二进制意义上正确地检测到性别存在,它只是不是正确的绝对计数。
  • 我刚刚更新了上面的例子,使它更符合真实的数据结构。
  • @Christopher 我还看不到。 :) 我很想知道是否有更好的方法
  • 现在我用 Counter() 添加了上面的脚本
  • @Christopher 很高兴知道。
猜你喜欢
  • 2023-01-09
  • 2016-01-09
  • 1970-01-01
  • 2012-10-12
  • 1970-01-01
  • 2020-10-23
  • 2016-02-29
  • 1970-01-01
  • 2020-12-29
相关资源
最近更新 更多