简体   繁体   English

优化在python中合并两个字典列表

[英]optimize merging two lists of dictionaries in python

i have two lists, each one contains 10-15k dictionaries.我有两个列表,每个列表包含 10-15k 字典。 the first list named campaigns and it contains dictionaries with the following structure:第一个名为campaigns列表,它包含具有以下结构的字典:

{u'campaign_id': u'400037', u'ctr': u'1.1210', u'roi': 0, u'end_date': None, u'revenue': 0.0, u'website_id': 1, u'enabled': u'active', u'budget': u'100.00', u'default_bid': u'0.05', u'cost': 30.63, u'start_date': u'2018-02-13'}

and the second list - yesterday_data dict's structure is:第二个列表 - yesterday_data _数据字典的结构是:

{u'cost': 0.0, u'campaign_id': u'400037', u'revenue': 0.0}

goal is to match campaign id's, and add two key's to the relevant dict in campaigns_data where yesterday_date["revenue"] and yesterday_date["cost"] will be a new keys in campaigns_data dict - yesterday_cost and yesterday_revenue目标是匹配活动 ID,并将两个键添加到campaigns_data中的相关字典中,其中yesterday_date["revenue"] _日期yesterday_date["revenue"]yesterday_date["cost"] _日期yesterday_date["cost"]将是campaigns_data字典中的新键 - yesterday_cost _ yesterday_date["cost"]yesterday_revenue _ yesterday_date["revenue"]

i managed to a achieve this logic with the following code:我设法用以下代码实现了这个逻辑:

campaigns = model.get_campaigns_data(self.mysql_db)
yesterday_data = model.get_yesterday_data(self.mysql_db, yesterday)
try:
    for campaign in campaigns:
        missing = filter(lambda c: c["campaign_id"] == str(campaign["campaign_id"]), yesterday_data)
        if not missing:
            pass
        else:
            campaign["yesterday_spend"] = missing[0]["cost"]
            campaign["yesterday_revenue"] = missing[0]["revenue"]

but with this numbers of dictionaries inside each list it's extremely slow and ,i want to believe, far fro being the optimized way to achieve that.但是每个列表中有这么多字典,它的速度非常慢,而且我想相信,远非实现这一目标的优化方式。 any idea how can i improve my code to get the same result?知道如何改进我的代码以获得相同的结果吗?

Group by id and reduce:id分组并减少:

grouper = {}
for d in campaigns_data:
    grouper[d["campaign_id"]] = d

# assuming the keys match up:

for d in yesterday_data:
    grouper[["campaign_id"]].update(yesterday_spend=d['cost'],
                                    yesterday_revenue=d['revenue'])

Try:尝试:

>>> d1 = {u'campaign_id': u'400037', u'ctr': u'1.1210', u'roi': 0, u'end_date': None, u'revenue': 0.0, u'website_id': 1, u'enabled': u'active', u'budget': u'100.00', u'default_bid': u'0.05', u'cost': 30.63, u'start_date': u'2018-02-13'}
>>> d2 = {u'cost': 0.0, u'campaign_id': u'400037', u'revenue': 0.0}

>>> if d1["campaign_id"] == d2["campaign_id"]:
      d1.update(d2)

Output输出

{u'roi': 0, u'ctr': u'1.1210', u'end_date': None, u'revenue': 0.0, u'website_id': 1, u'enabled': u'active', u'campaign_id': u'400037', u'budget': u'100.00', u'default_bid': u'0.05', u'cost': 0.0, u'start_date': u'2018-02-13'}

Use pandas to do this.使用熊猫来做到这一点。 Convert both these dictionaries to pandas dataframe and then merge them.将这两个字典都转换为 pandas 数据框,然后合并它们。

Note: I am doing this for one row.注意:我正在为一行执行此操作。 If you have 100 rows replace the index=[0] to index = range(100) in the lines where I am constructing df_1 and df_2如果您有 100 行,请在我构建df_1df_2行中将index=[0]替换为index = range(100)

campaigns = {u'campaign_id': u'400037', u'ctr': u'1.1210', u'roi': 0, u'end_date': None, u'revenue': 0.0, u'website_id': 1, u'enabled': u'active', u'budget': u'100.00', u'default_bid': u'0.05', u'cost': 30.63, u'start_date': u'2018-02-13'}

yesterday_data = {u'cost': 0.0, u'campaign_id': u'400037', u'revenue': 0.0}

import pandas as pd
df1 = pd.DataFrame(campaigns, index=[0])
df2 = pd.DataFrame(yesterday_data, index=[0])

df_new = df1.merge(df2, on=['campaign_id'])

to get back the dictionary form, do:要取回字典形式,请执行以下操作:

df_new.to_dict(orient='records')

Note 2 : The keys from yesterday_data for example, for example cost and revenue will end with _y as suffix and for keys from campaigns will have keys with suffix _x .注意 2 :例如,来自yesterday_data _数据的键,例如costrevenue将以_y作为后缀结尾,而对于来自campaigns键将具有后缀为_x键。 This is for the keys which are common between the two dataframes.这是用于两个数据帧之间共有的键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM