pandas column set value 使用多个列和多个条件
pandas column set value using multiple columns and multiple conditions
考虑这个示例数据:
data = {'January': [1,2,2,1,1], 'February': [1,1,2,0,0], 'March': [1,1,2,1,1], 'April': [1,1,2,0,0], 'May': [1,1,2,1,2], 'Frailty':['Moderate', 'Severe', 'Severe', 'Mild', 'Severe']}
sam_data = pd.DataFrame(data)
January February March April May Frailty
1 1 1 1 1 Moderate
2 1 1 1 1 Severe
2 2 2 2 2 Severe
1 0 1 0 1 Mild
1 0 1 0 2 Severe
我正在尝试创建最后一列 'Met_Gap',它使用以下逻辑:
如果 Frailty = 'Severe' 并且每一列(1 月至 5 月)的值至少为 2,则 'Met',否则 'Gap' AND
如果 Frailty 1= 'Severe' 并且每列(1 月至 5 月)的值至少为 1,则 'Met' 否则 'Gap'
我不能只添加这些列并得到总计,因为要实现 'Met' 每个月的列中必须有某种非 0 的值。
在下面尝试过,没有成功。
df['Met_Gap'] = np.where((df[df.columns[:5]] >= 10) & (df['Frailty'] == 'Severe'), 'Met', 'Gap')
有点卡住了,因为我已经评估了每一列是否不为 0,如果一列是 0,它会自动成为 'Gap.' 但是,如果所有列都非零,那么对于 'Severe' 它们必须至少为 2,对于其他类别,至少为 1。
预期输出:
January February March April May Frailty Met_Gap
1 1 1 1 1 Moderate Met
2 1 1 1 1 Severe Gap
2 2 2 2 2 Severe Met
1 0 1 0 1 Mild Gap
1 0 1 0 2 Severe Gap
我相信有创意的人以前遇到过这个问题。感谢您的观看。
IIUC,您可以使用布尔掩码和 numpy.where
/numpy.select
:
cols = list(sam_data.columns[:5])
# ['January', 'February', 'March', 'April', 'May']
s = sam_data[cols].min(axis=1) # min value per row
m = sam_data['Frailty'].eq('Severe')
sam_data['result'] = np.where((m&s.ge(2))|((~m)&s.ge(1)), 'Met', 'Gap')
# alternative to set different values Met1/Met2 for example
#sam_data['result'] = np.select([m&s.ge(2), (~m)&s.ge(1)], ['Met', 'Met'], 'Gap')
输出:
January February March April May Frailty result
0 1 1 1 1 1 Moderate Met
1 2 1 1 1 1 Severe Gap
2 2 2 2 2 2 Severe Met
3 1 0 1 0 1 Mild Gap
4 1 0 1 0 2 Severe Gap
考虑这个示例数据:
data = {'January': [1,2,2,1,1], 'February': [1,1,2,0,0], 'March': [1,1,2,1,1], 'April': [1,1,2,0,0], 'May': [1,1,2,1,2], 'Frailty':['Moderate', 'Severe', 'Severe', 'Mild', 'Severe']}
sam_data = pd.DataFrame(data)
January February March April May Frailty
1 1 1 1 1 Moderate
2 1 1 1 1 Severe
2 2 2 2 2 Severe
1 0 1 0 1 Mild
1 0 1 0 2 Severe
我正在尝试创建最后一列 'Met_Gap',它使用以下逻辑:
如果 Frailty = 'Severe' 并且每一列(1 月至 5 月)的值至少为 2,则 'Met',否则 'Gap' AND 如果 Frailty 1= 'Severe' 并且每列(1 月至 5 月)的值至少为 1,则 'Met' 否则 'Gap'
我不能只添加这些列并得到总计,因为要实现 'Met' 每个月的列中必须有某种非 0 的值。
在下面尝试过,没有成功。
df['Met_Gap'] = np.where((df[df.columns[:5]] >= 10) & (df['Frailty'] == 'Severe'), 'Met', 'Gap')
有点卡住了,因为我已经评估了每一列是否不为 0,如果一列是 0,它会自动成为 'Gap.' 但是,如果所有列都非零,那么对于 'Severe' 它们必须至少为 2,对于其他类别,至少为 1。
预期输出:
January February March April May Frailty Met_Gap
1 1 1 1 1 Moderate Met
2 1 1 1 1 Severe Gap
2 2 2 2 2 Severe Met
1 0 1 0 1 Mild Gap
1 0 1 0 2 Severe Gap
我相信有创意的人以前遇到过这个问题。感谢您的观看。
IIUC,您可以使用布尔掩码和 numpy.where
/numpy.select
:
cols = list(sam_data.columns[:5])
# ['January', 'February', 'March', 'April', 'May']
s = sam_data[cols].min(axis=1) # min value per row
m = sam_data['Frailty'].eq('Severe')
sam_data['result'] = np.where((m&s.ge(2))|((~m)&s.ge(1)), 'Met', 'Gap')
# alternative to set different values Met1/Met2 for example
#sam_data['result'] = np.select([m&s.ge(2), (~m)&s.ge(1)], ['Met', 'Met'], 'Gap')
输出:
January February March April May Frailty result
0 1 1 1 1 1 Moderate Met
1 2 1 1 1 1 Severe Gap
2 2 2 2 2 2 Severe Met
3 1 0 1 0 1 Mild Gap
4 1 0 1 0 2 Severe Gap