python - pandas apply() 函数无需返回值?/ 快速循环 df?
问题描述
我有一个大型(~145000 行)我正在研究的食谱数据库。我有一列“parsed_ingredients”,看起来像这样(每行多个字典):
[{'orig_name': '1,00 kg Kalbsbraten ',
'orig_amount': '1.00',
'orig_unit': 'kg',
'amount': 0.25,
'unit': 'g',
'splitted_ingredient': 'Kalbsbraten',
'splitted_slized_ingredient': 'Kalbsbraten',
'further_specification': '',
'alternatives': '',
'matched_ingredient_id': 'U030100',
'matched_ingredient_st': 'Kalb Hackfleisch roh',
'calorie': 148,
'protein': 19.726,
'carb': 0.0,
'fat': 7.713},
{'orig_name': '1,00 Zwiebel(n) ',
'orig_amount': '1.00',
'orig_unit': 'Anzahl',
'amount': 9.0,
'unit': 'g',
'splitted_ingredient': 'Zwiebel(n)',
...
]
基本上,我正在尝试为基于项目和基于用户(基于内容)的推荐系统准备我的 df,因此我正在尝试创建一个矩阵,其中包含配方中包含的每种成分的列。
我尝试了以下方法,但遇到的问题是,对于如此多的行,它非常慢:
for index, row in df.iterrows():
extracted_ingredient = ""
for ingredient in row["parsed_ingredients"]:
extracted_ingredient = ingredient["matched_ingredient_st"]
if not extracted_ingredient == "None":
df.loc[index, extracted_ingredient] = 1
因此,我尝试编写一个与 apply 一起使用的函数,因为我读到它的计算速度要快得多,但后来意识到 apply 总是希望我返回一些东西以保存在 DF 中(否则我会得到 'TypeError: 'NoneType' object is not callable' :
def ingredient_extraction(content, dataframe=df):
for newrow in content:
for entry in newrow:
if not entry["matched_ingredient_st"] == "None":
df[entry["matched_ingredient_st"]] = 1
df.apply(ingredient_extraction(df["parsed_ingredients"], df), axis=1)
有什么方法可以让熊猫将此功能应用于我的 df 吗?或者有没有更好的方法来加快在 iterrows 中完成的操作?
解决方案
只是一个想法的粗略轮廓。
假设你有一个像这样的 DataFrame:
recipe_id | parsed_ingredients
------------------------------
1 | [{...}, {...}, ...]
2 | [{...}, {...}, ...]
3 | [{...}, {...}, ...]
使用该explode
方法,展开 DataFrame 以每行显示一个成分字典。
df = df.explode('parsed_ingredients')
df.head()
recipe_id | parsed_ingredients
------------------------------
1 | {...}
1 | {...}
...
2 | {...}
2 | {...}
...
3 | {...}
3 | {...}
...
现在matched_ingredient_st
从每个字典中提取
df['matched_ingredient_st'] = df['parsed_ingredients'].apply(lambda x: x['matched_ingredient_st'])
df['match'] = 1 # Added for the next step
df.head()
recipe_id | parsed_ingredients | matched_ingredient_st | match
--------------------------------------------------------------
1 | {...} | ingredient_a | 1
1 | {...} | ingredient_b | 1
...
2 | {...} | ingredient_b | 1
2 | {...} | ingredient_d | 1
...
3 | {...} | ingredient_c | 1
3 | {...} | ingredient_d | 1
...
现在您可以使用内置的 pivot 方法将 DataFrame 还原为原始数据集中的类似格式
df = df.pivot(index='recipe_id ', columns='matched_ingredient_st ', values='match')
df.head()
| ingredient_a | ingredient_b | ingredient_c | ingredient_d
---------------------------------------------------------------
1 | 1 | 1 | 0 | 0 |
2 | 0 | 1 | 0 | 1 |
3 | 0 | 0 | 1 | 1 |
实际上并没有在 Python 中运行它,但是那里有逻辑和方法。
推荐阅读
- c# - 本地管理员检索其他登录进程 MainWindowTitle
- google-cloud-storage - 使用谷歌云存储、谷歌计算引擎和外部网站提供文件
- tabs - tns create app-name --template tns-template-drawer-navigation-ng
- python - 如何让 Python 文件打开到现有的 Spyder IDE 会话中
- javascript - 经常更新不同大小的顶点缓冲区部分
- python - MySQL插入一个条目,其中值数<列数
- android - 即时应用在奥利奥设备上未激活
- mysql - SQLite / MySQL 使用 LIKE 或 REGEXP 匹配 String 中的特殊内容词
- macos - 在 OSX 上安装 ocaml-top - GTK 问题
- java - Java中的优化方法