Skip to main content
 首页 » 编程设计

python之Pandas :Groupby 扩展应用和条件

2024年11月01日1zdz8207

我想对一列进行扩展,同时遵循基于另一列的条件:

df = pd.DataFrame({'_id': ['a','a', 'a', 'a', 'a'],  
                   'account': [1,2,3,2,5],  
                   'status':[3, 1, 5, 2, 7]}) 
 
  _id  account  status 
0   a        1       3 
1   a        2       1 
2   a        3       5 
3   a        2       2 
4   a        5       7 

这些行按时间顺序从最旧到最新排序,并显示用户 _idaccount 进行status 更改的时间。所以在这里我们可以看到用户 a 在某个时间点将帐户 2 标记为 status 1,然后将该值更新为 2

我需要一个 status_hist 列来显示所有 a 帐户的全局状态,其中全局状态定义为 min所有现有状态。在索引 0 处只有一个状态,因此 status_hist 为 3,在索引 1 处现在有两个状态',并且 status_hist 为 1,依此类推。当我们到达索引 3 时,全局状态应该从 1 变为 2,因为状态 account 2 现在已经改变了。

我可以使用 df.itertuples() 轻松完成此操作,但如果有更快的方法,我想避免这样做。这是 itertuples 解决方案,如果它有助于澄清我所追求的:

df2 = pd.DataFrame() 
 
for _, group in df.groupby('_id'): 
    res = [] 
    statuses = defaultdict() 
    for row in group.itertuples(): 
        statuses[row.account] = row.status 
        res.append(min(statuses.values())) 
 
    group['status_hist'] = res 
    df2 = df2.append(group) 

给出:

  _id  account  status  status_hist 
0   a        1       3            3 
1   a        2       1            1 
2   a        3       5            1 
3   a        2       2            2 
4   a        5       7            2 

谢谢,如果你能帮忙!

请您参考如下方法:

你可以使用get_dummies在“account”列上,乘以“status”中的 values。然后使用 mask 将 0 替换为 nan 以便能够 ffill 每组 '_id',最后在列上取 min比如:

df_dummies = pd.get_dummies(df.account)*df.status.values[:,None] 
df['status_hist'] = df_dummies.mask(df_dummies.eq(0)).groupby(df._id).ffill().min(axis=1) 
print (df) 
  _id  account  status  status_hist 
0   a        1       3          3.0 
1   a        2       1          1.0 
2   a        3       5          1.0 
3   a        2       2          2.0 
4   a        5       7          2.0