You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为DataFrame每行分配对应筛选后的食谱ID列表?

问题描述

需要为现有DataFrame fitbit_dt2 添加一列allwd_recipes,每行存储符合条件的整数(食谱ID)列表:筛选recp_some中不包含当前用户食物过敏原的所有食谱ID。

尝试两种方法均失败:

  1. 嵌套循环代码报错:
for i in fitbit_dt2.index:
    allwd_rcp = []
    for j in recp_some.index:
        if fitbit_dt2["Food Intolerances"][i] not in recp_some["ingredients"][j]:
            allwd_rcp.append(recp_some["id"][j])
    fitbit_dt2["allwd_recipes"][i] = fitbit_dt2["allwd_recipes"][i].apply(allwd_rcp)
  1. 列表推导式导致所有行分配同一个列表:
    fitbit_dt2["allwd_recipes"] = [allwd_rcp for i in fitbit_dt2.index]

数据集样例

fitbit_dt2 初始数据

idgenderFood Intolerances
0malePeanuts
1femaleNone
2maleNone
3femaleKiwi
4femaleMilk
5maleWheat
6maleNone

recp_some 食谱数据

idingredients
10354["romaine lettuce","black olives","grape tomatoes","garlic","pepper","purple onion","seasoning","garbanzo beans","feta cheese crumbles"]
2645["water","vegetable oil","wheat","salt"]
12734["italian seasoning","broiler-fryer chicken","mayonaise","zesty italian dressing"]
2941["sugar","hot chili","fish sauce","lime juice","peanuts"]
40254["bananas","pineapple juice","cherries","coconut rum","cranberry juice","full fat milk","rum","kiwi"]

期望输出

idgenderFood Intolerancesallwd_recipes
0malePeanuts[10354,2645,12734,40254]
1femaleNone[10354,2645,12734,2941,40254]
2maleNone[10354,2645,12734,2941,40254]
3femaleKiwi[10354,2645,12734,2941]
4femaleMilk[2645,12734,2941]
5maleWheat[10354,12734,2941,40254]
6maleNone[10354,2645,12734,2941,40254]

修正方案

方法1:用apply逐行处理(简洁高效)

利用Pandas的apply方法,对每行单独计算符合条件的食谱ID列表,避免冗余循环和错误:

# 定义函数:输入过敏原,返回允许的食谱ID列表
def get_allowed_recipes(intolerance):
    if intolerance == "None":
        return recp_some["id"].tolist()
    # 筛选不包含过敏原的食谱,提取ID转为列表
    mask = ~recp_some["ingredients"].apply(lambda x: intolerance in x)
    return recp_some.loc[mask, "id"].tolist()

# 为fitbit_dt2添加新列
fitbit_dt2["allwd_recipes"] = fitbit_dt2["Food Intolerances"].apply(get_allowed_recipes)

方法2:修复原循环逻辑(适合理解底层逻辑)

如果坚持用循环,需修正赋值逻辑并避免链式索引警告:

# 初始化新列为独立空列表
fitbit_dt2["allwd_recipes"] = [[] for _ in range(len(fitbit_dt2))]

for i in fitbit_dt2.index:
    allwd_rcp = []
    intolerance = fitbit_dt2.loc[i, "Food Intolerances"]
    for j in recp_some.index:
        if intolerance == "None" or intolerance not in recp_some.loc[j, "ingredients"]:
            allwd_rcp.append(recp_some.loc[j, "id"])
    # 用.loc赋值避免链式索引问题
    fitbit_dt2.loc[i, "allwd_recipes"] = allwd_rcp

关键错误说明

  1. 第一种尝试错误:fitbit_dt2["allwd_recipes"][i].apply(allwd_rcp)逻辑混乱,apply是Series/DataFrame的方法,不能直接对单个列表调用,此处直接赋值列表即可。
  2. 第二种尝试错误:列表推导式引用了外部同一个allwd_rcp对象,所有行共享同一内存地址,导致所有行内容完全相同;需在推导式内创建新列表,或用apply自动生成独立列表。

内容的提问来源于stack exchange,提问作者Kavya Nagesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:06:04