【问题标题】:optimize merging two lists of dictionaries in python优化在python中合并两个字典列表
【发布时间】:2018-02-14 15:54:04
【问题描述】:

我有两个列表,每个列表包含 10-15k 字典。 第一个名为 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 dict的结构是:

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

目标是匹配活动 ID,并在 campaigns_data 中的相关字典中添加两个键,其中 yesterday_date["revenue"]yesterday_date["cost"] 将是 campaigns_data 字典中的新键 - yesterday_costyesterday_revenue

我设法用以下代码实现了这个逻辑:

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"]

但是每个列表中有这么多字典,速度非常慢,而且我想相信,远非实现这一目标的优化方式。 知道如何改进我的代码以获得相同的结果吗?

【问题讨论】:

  • 反转字典。使其 campaign_id 成为键并映射到每个数据集对应字典的引用,然后您可以循环其中一个并在 O(n) 中完成。

标签: python dictionary optimization


【解决方案1】:

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'])

【讨论】:

    【解决方案2】:

    试试:

    >>> 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)
    

    输出

    {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'}
    

    【讨论】:

      【解决方案3】:

      使用 pandas 来执行此操作。将这两个字典都转换为 pandas 数据框,然后合并它们。

      注意:我这样做是为了一排。如果您有 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'])
      

      要取回字典形式,请执行以下操作:

      df_new.to_dict(orient='records')
      

      注 2: 来自yesterday_data 的键,例如costrevenue 将以_y 作为后缀,而来自campaigns 的键将具有带有后缀_x 的键。这适用于两个数据帧之间共有的键。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-02
        • 1970-01-01
        • 2016-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多