【问题标题】:Elegant way to fill in a column with row values based on groups in pandas根据 pandas 中的组用行值填充列的优雅方法
【发布时间】:2019-08-13 09:42:18
【问题描述】:

我有一个如下所示的数据框

data_file= pd.DataFrame({'person_id':[1,1,1,1,2,2,2,3,3,3],'ob.date': [np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan],
                 'observation': ['Age','interviewdate','marital_status','interviewdate','Age','interviewdate','marital_status','Age','interviewdate','marital_status'],
                 'answer': [21,'21/08/2017','Single','22/05/2217', 26,'11/03/2010','Single',41,'31/09/2012','Married']
                 })

我想做的是,从answer 列中获取date values 并将其放入ob.date 列中。提供的数据框显示person_id =121/08/2017 上回答了关于年龄的问题,在22/05/2017 上回答了关于marital_status 的问题

这是我根据另一篇帖子的 SO 建议尝试的方法

s = data_file[(data_file.observation == 'interviewdate')].set_index('person_id')['answer']
data_file['ob.date'] = data_file['person_id'].map(s)

但这不起作用,因为我得到了duplicate index error。我怎样才能避免这个问题并使其足够高效?

因此,任何优雅高效的解决方案都会有所帮助。 Person_id = 1 有两个日期值,因此用来自answer 列(interviewdate 观察)的值填充interviewdate 观察上方的所有行

我怎么能期望我的输出是这样的?

【问题讨论】:

  • 第一个person_id 的策略是什么?在匹配日期之前填写interviewdate上方的所有行?
  • 是的。多于。你是对的。

标签: python python-3.x pandas dataframe pandas-groupby


【解决方案1】:

所有依赖于数据 - 首先通过answer 按条件设置新列,然后每组通过前后填充替换缺失值:

data_file['ob.date']  = data_file.loc[(data_file.observation == 'interviewdate'), 'answer']
data_file['ob.date'] = (data_file.groupby('person_id')['ob.date']
                                 .apply(lambda x: x.bfill().ffill()))


print (data_file)

   person_id     ob.date     observation      answer
0          1  21/08/2017             Age          21
1          1  21/08/2017   interviewdate  21/08/2017
2          1  22/05/2217  marital_status      Single
3          1  22/05/2217   interviewdate  22/05/2217
4          2  11/03/2010             Age          26
5          2  11/03/2010   interviewdate  11/03/2010
6          2  11/03/2010  marital_status      Single
7          3  31/09/2012             Age          41
8          3  31/09/2012   interviewdate  31/09/2012
9          3  31/09/2012  marital_status     Married

详情

First 用于每个组的反向归档,因为interviewdate 是边缘行 - 之前的所有值都是相同的子组。最后是添加前向填充以替换每个组的最后一个 NaN - 不被 bfill 替换:

data_file['ob.date'] = (data_file.groupby('person_id')['ob.date']
                                   .apply(lambda x: x.bfill()))


print (data_file)

   person_id     ob.date     observation      answer
0          1  21/08/2017             Age          21
1          1  21/08/2017   interviewdate  21/08/2017
2          1  22/05/2217  marital_status      Single
3          1  22/05/2217   interviewdate  22/05/2217
4          2  11/03/2010             Age          26
5          2  11/03/2010   interviewdate  11/03/2010
6          2         NaN  marital_status      Single
7          3  31/09/2012             Age          41
8          3  31/09/2012   interviewdate  31/09/2012
9          3         NaN  marital_status     Married

【讨论】:

  • 我也有同样的想法,但是如果面试日期早于一个有多个面试日期(例如第 0 行和第 1 行交换)的人的相应观察结果怎么办?此解决方案将填写此人下一个问题的面试日期,这可能不是 OP 的意图:他编写了不依赖职位的解决方案
  • @Stef - 是的 - 这就是All depends of data开始解释的原因
  • 我将此标记为解决方案,因为数据必须采用某种结构才能编码。因此,我从我的问题中删除了关于位置的约束
  • 你能帮我解决这个@jezrael 吗? stackoverflow.com/questions/57550238/…
猜你喜欢
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-21
  • 1970-01-01
  • 2020-04-12
  • 2020-11-14
  • 1970-01-01
相关资源
最近更新 更多