如果条件不起作用,则创建一个列
Create a column under if condition doesn't work
我有一个数据框,其中包含一些每日、每月和每周的统计数据以及减肥情况。
我想创建一个布尔列,其中包含丢失的体重是大于还是小于阈值的信息。我尝试使用 if
循环和 np.where
if df_prod_stats.loc[df_prod_stats['frequency'] == "daily"]:
df_prod_stats['target_met'] =np.where(((df_prod_stats['loss_weight'] < 0.5)),1,0)
elif df_prod_stats.loc[df_prod_stats['frequency'] == "monthly"]:
df_prod_stats['target_met'] =np.where(((df_prod_stats['loss_weight'] < 15)),1,0)
else:
df_prod_stats['target_met'] =np.where(((df_prod_stats['loss_weight'] < 3.5)),1,0)
但是我得到一个错误:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
我认为您需要以不同的方式执行此操作。我认为您正在尝试遍历每一行以查看它是否为 weekly/monthly 并相应地检查损失重量,但这并不是您的代码实际执行的操作。在 if df_prod_stats.loc[...]
中,loc
将 return 数据框的一个子集,如果它有数据,它将评估为 true,但是你的下一行尝试填写新的column 将只应用于整个原始数据框,而不是与 loc
语句匹配的行。您可以使用以下几个 loc
语句实现(我认为)您想要的:
创建 target_met 列并设置为 0:
df_prod_stats['target_met'] = 0
然后用.loc过滤你的第一个if语句条件(频率是每天,减重小于0.5),设置target met为1:
df_prod_stats.loc[(df_prod_stats['frequency'] == 'daily')
& (df_prod_stats['loss_weight'] < 0.5), 'target_met'] = 1
elif条件(频率为每月,减肥小于15):
df_prod_stats.loc[(df_prod_stats['frequency'] == 'monthly')
& (df_prod_stats['loss_weight'] < 15), 'target_met'] = 1
else条件(频率既不是每天也不是每月,减重小于3.5):
df_prod_stats.loc[~(df_prod_stats['frequency'].isin(['daily', 'monthly']))
& (df_prod_stats['loss_weight'] < 3.5), 'target_met'] = 1
放在一起你得到:
df_prod_stats['target_met'] = 0
df_prod_stats.loc[(df_prod_stats['frequency'] == 'daily')
& (df_prod_stats['loss_weight'] < 0.5), 'target_met'] = 1
df_prod_stats.loc[(df_prod_stats['frequency'] == 'monthly')
& (df_prod_stats['loss_weight'] < 15), 'target_met'] = 1
df_prod_stats.loc[~(df_prod_stats['frequency'].isin(['daily', 'monthly']))
& (df_prod_stats['loss_weight'] < 3.5), 'target_met'] = 1
输出:
frequency loss_weight target_met
0 daily -0.42 1
1 daily -0.35 1
2 daily -0.67 1
3 daily -0.11 1
4 daily -0.31 1
我希望这就是您要实现的目标。
我发现也可以在 np.where
中使用简单的条件集,如下所示:
df_prod_stats['target_met'] =np.where(((df_prod_stats['loss_weight'] < 0.5) & ( df_prod_stats['frequency'] == "daily")
| (df_prod_stats['loss_weight'] < 15.0) & ( df_prod_stats['frequency'] == "monthly")
| (df_prod_stats['loss_weight'] < 3.5) & ( df_prod_stats['frequency'] == "weekly")),1,0)
我有一个数据框,其中包含一些每日、每月和每周的统计数据以及减肥情况。
我想创建一个布尔列,其中包含丢失的体重是大于还是小于阈值的信息。我尝试使用 if
循环和 np.where
if df_prod_stats.loc[df_prod_stats['frequency'] == "daily"]:
df_prod_stats['target_met'] =np.where(((df_prod_stats['loss_weight'] < 0.5)),1,0)
elif df_prod_stats.loc[df_prod_stats['frequency'] == "monthly"]:
df_prod_stats['target_met'] =np.where(((df_prod_stats['loss_weight'] < 15)),1,0)
else:
df_prod_stats['target_met'] =np.where(((df_prod_stats['loss_weight'] < 3.5)),1,0)
但是我得到一个错误:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
我认为您需要以不同的方式执行此操作。我认为您正在尝试遍历每一行以查看它是否为 weekly/monthly 并相应地检查损失重量,但这并不是您的代码实际执行的操作。在 if df_prod_stats.loc[...]
中,loc
将 return 数据框的一个子集,如果它有数据,它将评估为 true,但是你的下一行尝试填写新的column 将只应用于整个原始数据框,而不是与 loc
语句匹配的行。您可以使用以下几个 loc
语句实现(我认为)您想要的:
创建 target_met 列并设置为 0:
df_prod_stats['target_met'] = 0
然后用.loc过滤你的第一个if语句条件(频率是每天,减重小于0.5),设置target met为1:
df_prod_stats.loc[(df_prod_stats['frequency'] == 'daily')
& (df_prod_stats['loss_weight'] < 0.5), 'target_met'] = 1
elif条件(频率为每月,减肥小于15):
df_prod_stats.loc[(df_prod_stats['frequency'] == 'monthly')
& (df_prod_stats['loss_weight'] < 15), 'target_met'] = 1
else条件(频率既不是每天也不是每月,减重小于3.5):
df_prod_stats.loc[~(df_prod_stats['frequency'].isin(['daily', 'monthly']))
& (df_prod_stats['loss_weight'] < 3.5), 'target_met'] = 1
放在一起你得到:
df_prod_stats['target_met'] = 0
df_prod_stats.loc[(df_prod_stats['frequency'] == 'daily')
& (df_prod_stats['loss_weight'] < 0.5), 'target_met'] = 1
df_prod_stats.loc[(df_prod_stats['frequency'] == 'monthly')
& (df_prod_stats['loss_weight'] < 15), 'target_met'] = 1
df_prod_stats.loc[~(df_prod_stats['frequency'].isin(['daily', 'monthly']))
& (df_prod_stats['loss_weight'] < 3.5), 'target_met'] = 1
输出:
frequency loss_weight target_met
0 daily -0.42 1
1 daily -0.35 1
2 daily -0.67 1
3 daily -0.11 1
4 daily -0.31 1
我希望这就是您要实现的目标。
我发现也可以在 np.where
中使用简单的条件集,如下所示:
df_prod_stats['target_met'] =np.where(((df_prod_stats['loss_weight'] < 0.5) & ( df_prod_stats['frequency'] == "daily")
| (df_prod_stats['loss_weight'] < 15.0) & ( df_prod_stats['frequency'] == "monthly")
| (df_prod_stats['loss_weight'] < 3.5) & ( df_prod_stats['frequency'] == "weekly")),1,0)