我需要为 df 中的患者创建一个列表,根据他们的 BMI 和是否吸烟将他们分类为“高”、“中”或“低”。当我当前运行代码时,所有六个条目都为“中”。 (使用了假名和数据)
df = pd.DataFrame({'Name':['Jordan', 'Jess', 'Jake', 'Alice', 'Alan', 'Lauren'],
'Age':[26, 23, 19, 20, 24, 28],
'Sex':['M', 'F' , 'M', 'F', 'M', 'F'],
'BMI':[26, 22, 24, 17, 35, 20],
'Smokes':['No', 'No', 'Yes', 'No', 'Yes', 'No']})
risk_list = []
for i in df.Name:
if df.BMI.any() > 30 | df.BMI.any() < 19.99 | df.Smokes.any() == "Yes":
risk_list.append("High")
elif df.BMI.any() >= 25 & df.BMI.any() <= 29.99:
risk_list.append("Medium")
elif df.BMI.any() < 24.99 & df.BMI.any() > 19.99 and df.Smokes.any() == "No":
risk_list.append("Low")
print(risk_list)
输出:
['Medium', 'Medium', 'Medium', 'Medium', 'Medium', 'Medium']
就此而言,我是 Pandas 和 Python 的新手。我想我很接近但无法弄清楚为什么我的数据没有被正确返回。
谢谢。
答案 0 :(得分:4)
你的代码中有很多东西。仅举几例:
你需要几个括号:df.BMI.any() > 30 | df.BMI.any() < 19.99
应该是 (df.BMI.any() > 30) | (df.BMI.any() < 19.99)
&
与 and
循环内的所有内容,例如df.BMI.any()
独立于您正在查看的行,即 Name
,因此您会在任何地方获得相同的值。
我认为您可以使用 np.select
:
np.select([df.BMI.gt(30) | df.BMI.lt(19.99) | df.Smokes.eq('Yes'),
df.BMI.between(25,29.99)],
['High', 'Medium'], 'Low')
输出:
array(['Medium', 'Low', 'High', 'High', 'High', 'Low'], dtype='<U6')
答案 1 :(得分:2)
除了@QuangHoang 的回答之外,对数据帧进行迭代也有些直观。您使用 .iterrows()
,而不是您的 Name
列,因为这不是字典。
risk_list = []
for _, i in df.iterrows():
if i.BMI > 30 or i.BMI < 19.99 or i.Smokes == "Yes":
risk_list.append("High")
elif i.BMI >= 25 and i.BMI <= 29.99:
risk_list.append("Medium")
elif i.BMI < 24.99 and i.BMI > 19.99 and i.Smokes == "No":
risk_list.append("Low")
>>> print(risk_list)
['Medium', 'Low', 'High', 'High', 'High', 'Low']
答案 2 :(得分:2)
您可以将其定义为函数并将其传递给 .apply()
:
def risk_eval(row):
if row.BMI > 30 | row.BMI < 19.99 | row.Smokes== "Yes":
return "High"
elif row.BMI >= 25 & row.BMI <= 29.99:
return"Medium"
elif rowBMI < 24.99 & row.BMI> 19.99 and row.Smokes == "No":
return "Low"
df['Risk'] = df.apply(lambda x: risk_eval(x),axis=1)
然后获取列表:
df['Risk'].values.tolist()