Python 将自定义功能应用于数据库

Python 将自定义功能应用于数据库,python,pandas,function,dataframe,recursion,Python,Pandas,Function,Dataframe,Recursion,我定义了以下函数,该函数在嵌套字典中搜索特定键的值 def get_recursively(search_dict, field): fields_found = [] if len(search_dict) == 1: search_dict = search_dict[0] for key, value in search_dict.items(): if key == field: fields_fou

我定义了以下函数,该函数在嵌套字典中搜索特定键的值

def get_recursively(search_dict, field):

    fields_found = []

    if len(search_dict) == 1:
        search_dict = search_dict[0]

    for key, value in search_dict.items():

        if key == field:
            fields_found.append(value)

        elif isinstance(value, dict):
            results = get_recursively(value, field)
            for result in results:
                fields_found.append(result)

        elif isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    more_results = get_recursively(item, field)
                    for another_result in more_results:
                        fields_found.append(another_result)

    return fields_found
现在让我们假设我想把这个函数应用到df中的一列,并将结果保存在一个新列中。我的数据如下所示:

id              metadata                    field
123             {"dek": "fashion...}        frontend
124.            {"dek": "house...}          frontend
我尝试了以下代码:

df['NewCol'] = df.apply(lambda x: get_recursively(x['metadata'], x['field']), axis=1)
因此,在本例中,我将传递列
metadata
和列
字段
的值,该字段是作为参数的“前端”。我得到了一个错误:
KeyError:(0,'发生在索引2')
当我在一个保存在变量中的嵌套字典上测试我的函数时,它正好提供了我所需要的,即键-前端的值。我做错了什么

下面提供了我正在处理的嵌套dict示例:

{"dek": "<p>Don\'t forget to buy a card</p>", "links": {"edit": {"dev": "//patty-menshealth.feature.hearstapps.net/en/content/edit/76517422-96ad-4b5c-a24a-c080c58bce0c", "prod": "//patty-menshealth.prod.hearstapps.com/en/content/edit/76517422-96ad-4b5c-a24a-c080c58bce0c", "stage": "//patty-menshealth.stage.hearstapps.net/en/content/edit/76517422-96ad-4b5c-a24a-c080c58bce0c"}, "frontend": {"dev": "//menshealth.feature.hearstapps.net/trending-news/a19521193/fathers-day-weekend-plans/", "prod": "//www.menshealth.com/trending-news/a19521193/fathers-day-weekend-plans/", "stage": "//menshealth.stage.hearstapps.net/trending-news/a19521193/fathers-day-weekend-plans/"}}, "header": {"title_color": 1, "title_layout": 1}, "sponsor": {"program_type": 1, "tracking_urls": []}, "social_dek": "<p>Don\'t forget to buy a card</p>", "auto_social": 0, "index_title": "\u200bWeekend Guide: Treat Your Dad Right This Father\'s Day", "short_title": "Treat Your Dad Right This Father\'s Day", "social_title": "\u200bWeekend Guide: Treat Your Dad Right This Father\'s Day", "editors_notes": "<p>nid: 2801076<br>created_date: 2017-06-16 13:00:01<br>compass_feed_date: 2017-06-21 14:01:58<br>contract_id: 40</p>", "seo_meta_title": "Treat Your Dad Right This Father\'s Day\u200b | Men’s Health", "social_share_url": "/trending-news/a19521193/fathers-day-weekend-plans/", "seo_related_links": {}, "editor_attribution": "by", "hide_from_homepage": 1, "syndication_rights": 3, "seo_meta_description": "\u200bFrom gifts to food ideas, we\'ve got your Father\'s Day covered. Just don\'t forget to buy him a card."}
{dek:“别忘了买一张卡,

”,“链接”:{“编辑”:“//patty menshealth.feature.hearstaps.net/en/content/edit/76517422-96ad-4b5c-a24a-c080c58bce0c”,“prod://patty menshealth.prod.hearstaps.com/en/content/edit/76517422-96ad-4b5c-c080c58bce0c”,“stage”://patty menshhealth.stage.hearstapps.net/en/content/edit/76517422-96ad-4b5c-a24a-c080c58bce0c“,“前端”:{“开发”:“//menshhealth.feature.hearstapps.net/trending news/a19521193/父亲节周末计划/,“产品”:“//www.menshhealth.com/trending news/a19521193/父亲节周末计划/,“阶段”:”//menshealth.stage.Hearttaps.net/trending news/a19521193/fathers day weekend plans/“}”,header:{“标题颜色”:1,“标题布局”:1},“赞助商”:{“节目类型”:1,“跟踪网址”:[]},“社交性”:“别忘了买一张卡片”;“自动社交性”:0,“索引标题”:“\u200bWeekend指南:在父亲节好好对待你的父亲”,“简短标题:“在父亲节正确对待你的父亲”,“社交标题”:“\u200b周末指南:在父亲节正确对待你的父亲”,“编辑笔记”:“nid:2801076
创建日期:2017-06-16 13:00:01
compass\u feed\u日期:2017-06-21 14:01:58
合同id:40

,“seo\u meta\u title”:”在这个父亲节正确对待你的父亲\u200b男性健康“,”社会共享url“/”趋势新闻/a19521193/父亲节周末计划“,”搜索引擎优化相关链接“,”编辑归属“,”作者“,”隐藏主页“:1,“联合权利“,”搜索引擎优化元数据描述“:”\U200B从礼物到食物的创意,我们已经涵盖了你父亲节。只是别忘了给他买张贺卡。”}
键错误似乎是由第一条if语句引起的:

if len(search_dict) == 1:
    search_dict = search_dict[0]
我在Dict类型检查方面遇到了问题,选择尝试使用collections.Mapping而不是Dict。我测试了下面的解决方案,它似乎很有效

导入集合
def递归获取(搜索指令,字段):
字段_found=[]
对于键,搜索目录项()中的值:
如果键==字段:
找到字段\追加(值)
elif isinstance(值、集合.映射):
结果=递归获取(值、字段)
对于结果中的结果:
找到字段。\u追加(结果)
elif isinstance(值、列表):
对于有价值的项目:
如果存在(项目,指令):
更多结果=递归获取(项、字段)
对于另一个导致更多结果的结果:
字段\已找到。追加(另一个\结果)
返回未找到的字段

确保您的元数据是命令对象。还要仔细检查列名。@Poojan当我运行
打印(type(df['metadata'])
时,它说:
而不是
应用
我想您可以使用列表理解:
df[“NewCol”]=[get_递归(*a)表示zip中的a(df[“metadata”],df[“field”])
@HenryYik运行了您的代码,但出现了一个错误:
keyrerror:0
:/因此这是您的函数的问题。可能在第
search\u dict=search\u dict[0]行中。