[英]Why isn't my inner loop working correctly?
我对 Pandas 数据帧比较陌生。 我有以下代码和 For 嵌套循环。
当循环碰到内循环时,就会出现问题。
import pandas as pd
### Create Data Frames:
Patients = {'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']}
pdf = pd.DataFrame(Patients)
print(pdf) ## DF printed out completely
##
i = 0
for Smokes in pdf.Smokes:
if Smokes == 'Yes':
pdf.at[i, 'Risk'] = 'high'
else:
pdf.at[i, 'Risk'] = ' '
for BMI in pdf.BMI:
if BMI >= 30 or BMI <= 19:
pdf.at[i, 'Risk'] = 'high'
elif BMI >= 25 and BMI <=29:
pdf.at[i, 'Risk'] = 'medium'
else:
pdf.at[i, 'Risk'] = 'Low'
i +=1 #
但是,当我再次打印出 pdf 时,它显示:
Name Age Sex BMI Smokes Risk
0 Jordan 26 M 26 No Low
1 Jess 23 F 22 No Low
2 Jake 19 M 24 Yes high
3 Alice 20 F 17 No Low
4 Alan 24 M 35 Yes high
5 Lauren 28 F 20 No Low
Jordan 应该是中等风险患者,Alice 应该是低风险患者,但内部循环没有意识到这一点。 但是,当我单独运行 BMI 循环时,它会识别它。
不要循环。 使用np.select
创建条件层次结构和相应的选择并分配正确的值。 它优先于条件中找到的第一个True
,因此我们将其排序为'high'
、 'medium'
、 'low'
。
import numpy as np
conditions = [df['Smokes'].eq('Yes') | df['BMI'].ge(30) | df['BMI'].le(19), # high
df['BMI'].between(25, 30)] # medium
choice_list = ['high', 'medium']
df['Risk'] = np.select(conditions, choice_list, default='low')
Name Age Sex BMI Smokes Risk
0 Jordan 26 M 26 No medium
1 Jess 23 F 22 No low
2 Jake 19 M 24 Yes high
3 Alice 20 F 17 No high
4 Alan 24 M 35 Yes high
5 Lauren 28 F 20 No low
在第一个else
语句中,您有一个for
循环,它再次评估所有Risk
值,您应该在没有内部for
循环的情况下使用您的代码:
if Smokes == 'Yes':
pdf.at[i, 'Risk'] = 'high'
elif pdf.at[i, 'BMI'] >= 30 or pdf.at[i, 'BMI'] <= 19:
pdf.at[i, 'Risk'] = 'high'
elif pdf.at[i, 'BMI'] >= 25 and pdf.at[i, 'BMI'] <=29:
pdf.at[i, 'Risk'] = 'medium'
else:
pdf.at[i, 'Risk'] = 'Low'
在您的代码中进行这些小改动 pdf 将是:
可能值得将您的代码重构为类似
def get_risk(row):
if row['Smokes'] == 'Yes':
return 'high'
elif row['BMI'] >= 30 or row['BMI'] <= 19:
return 'high'
elif row['BMI'] >= 25 and row['BMI'] <=29:
return 'medium'
else:
return 'low'
pdf['Risk'] = pdf.apply(get_risk, axis=1)
我不确定您的风险计算中的逻辑是否能满足您的期望。 我从您的示例中逐字复制它。
通常在使用 pandas 数据帧时,有一些有效的方法可以在不使用for
循环的情况下完成任务。 在您的情况下,您可以定义返回“风险”值字符串的 function 并将其apply
每行的列以设置所需的新列:
import pandas as pd
# create dataframe
Patients = {'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']}
pdf = pd.DataFrame(Patients)
# inspect dataframe
print(pdf)
# define the function that you want to apply
def get_risk(series):
if series.Smokes == 'Yes':
return 'high'
else:
if series.BMI >= 30 or series.BMI <= 19:
return 'high'
elif series.BMI >= 25 and series.BMI <= 29:
return 'medium'
else:
return 'low'
# apply the function across the columns of the dataframe (sending each row to the function as a series)
pdf['Risk'] = pdf.apply(get_risk, axis='columns')
# inspect the results
print(pdf)
您的内部 for 循环完成并设置pdf.at[i, 'Risk'] = 'Low'
因为最后一个 BMI(20)很好。 这发生在外循环的每个循环上。
import pandas as pd
### Create Data Frames:
Patients = {'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']}
pdf = pd.DataFrame(Patients)
risk = []
for index,rows in pdf.iterrows():
if rows['Smokes'] == 'Yes':
risk.append('high')
else:
BMI = rows['BMI']
if BMI >= 30 or BMI <= 19:
risk.append('high')
elif BMI >= 25 and BMI <=29:
risk.append('medium')
else:
risk.append('Low')
pdf['risk']=risk
说明: iterrows() 有助于遍历 dataframe 的每一行。 'rows' 将包含所有值。 PS Alice 将处于高风险状态,因为 BMI 低于 19。我考虑了一个单独的列表“风险”,我在其中为每一行附加值并最后在 dataframe 中添加此列
使用它代替 for 循环,它非常干净和快速:
import numpy as np
pdf['Risk'] = np.where(pdf['Smokes']=='Yes', 'High','none')
pdf['Risk'] = np.where(np.logical_and(pdf['Smokes']=='No', pdf['Age']==26), 'medium','none')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.