我想对一列进行扩展,同时遵循基于另一列的条件:
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
这些行按时间顺序从最旧到最新排序,并显示用户 _id
对 account
进行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