【问题标题】:Compare multiple values of dictionary and aggregate result比较字典的多个值并聚合结果
【发布时间】:2021-01-07 19:08:17
【问题描述】:

我有这个用例,我需要在比较值时忽略 skutargetFlagqualifierFlag,如果列表的任何字典具有除这三个以外的相同值,则应将其聚合为一个字典以及所有这三个键和值。

谁能告诉我我需要做哪些修改或任何其他更好的解决方案才能获得正确的结果。

到目前为止我尝试的解决方案在与上述选项进行比较时只能取一个值:

from collections import OrderedDict
import pandas as pd

d = OrderedDict()

d = (pd.DataFrame(lst)
            .groupby(['endDate','storeCode', 'startDate', 'promoName','targetFlag', 'qualifierFlag'])
            .sku
            .agg(set)
            .reset_index()
            .to_dict('r'))
lt = [{
   "sku":"40428200",
   "storeCode":"316",
   "endDate":"05445100",
   "promoName":"2201:316 SUPER 37100548200",
   "startDate":"40505000",
   "targetFlag":"0",
   "qualifierFlag":"0",
},
{
   "sku":"4567",
   "storeCode":"316",
   "endDate":"05445100",
   "promoName":"2201:316 SUPER 37100548200",
   "startDate":"40505000",
   "targetFlag":"1",
   "qualifierFlag":"1",
},
{
   "sku":"12345",
   "storeCode":"123",
   "endDate":"05445100",
   "promoName":"2201:316 GRAND 0548200",
   "startDate":"40505000",
   "targetFlag":"1",
   "qualifierFlag":"0",
},
{
   "sku":"40428200",
   "storeCode":"316",
   "endDate":"18840100",
   "promoName":"2201:316 AVI 37125790200",
   "startDate":"40505000",
   "targetFlag":"1",
   "qualifierFlag":"0",
}
]

预期的结果会是这样的

[
 {'endDate': '05445100',
  'promoName': '2201:316 GRAND 37100548200',
  'startDate': '40505000',
  'storeCode': '123',
  'res': [
      {
        'qualifierFlag': '0',
        'sku': '12345',
        'targetFlag': '1'
      }
  ]
  },
 {'endDate': '05445100',
  'promoName': '2201:316 SUPER 37100548200',
  'startDate': '40505000',
  'storeCode': '316',
  'res': [
      {
        'qualifierFlag': '0',
        'sku': '40428200',
        'targetFlag': '0'
      },
      {
        'qualifierFlag': '1',
        'sku': '4567',
        'targetFlag': '1'
      },
  ]
  },
 {'endDate': '18840100',
  'promoName': '2201:316 AVI 37125790200',
  'startDate': '40505000',
  'storeCode': '316',
  'res': [
      {
        'qualifierFlag': '0',
        'sku': '40428200',
        'targetFlag': '1'
      }
  ]
]

【问题讨论】:

    标签: python pandas dictionary lambda itertools


    【解决方案1】:

    使用itertools.groupby

    from itertools import groupby
    
    def key_func(x):
        return (x["storeCode"], x["promoName"], x["startDate"], x["endDate"])
    
    lst = sorted(lst, key=key_func)
    
    result = [
        {
            "storeCode": k[0],
            "promoName": k[1],
            "startDate": k[2],
            "endDate": k[3],
            "res": [
                {
                    "sku": x["sku"],
                    "qualifierFlag": x["qualifierFlag"],
                    "targetFlag": x["targetFlag"],
                }
                for x in list(v)
            ],
        }
        for k, v in groupby(lst, key=key_func)
    ]
    

    结果:

    [
        {
            "storeCode": "123",
            "promoName": "2201:316 GRAND 0548200",
            "startDate": "40505000",
            "endDate": "05445100",
            "res": [{"sku": "12345", "qualifierFlag": "0", "targetFlag": "1"}],
        },
        {
            "storeCode": "316",
            "promoName": "2201:316 AVI 37125790200",
            "startDate": "40505000",
            "endDate": "18840100",
            "res": [{"sku": "40428200", "qualifierFlag": "0", "targetFlag": "1"}],
        },
        {
            "storeCode": "316",
            "promoName": "2201:316 SUPER 37100548200",
            "startDate": "40505000",
            "endDate": "05445100",
            "res": [
                {"sku": "40428200", "qualifierFlag": "0", "targetFlag": "0"},
                {"sku": "4567", "qualifierFlag": "1", "targetFlag": "1"},
            ],
        },
    ]
    

    Jean-Marc Billod 的方法使用 set 作为聚合函数,因此只返回唯一值。

    【讨论】:

    • 完美!谢谢:)
    【解决方案2】:

    下面的代码能解决问题吗?

    d = (pd.DataFrame(lst)
           .groupby(['endDate','storeCode', 'startDate', 'promoName'])['sku', 'targetFlag', 'qualifierFlag']
           .agg(set)
           .reset_index()
           .to_dict('r'))
    

    【讨论】:

    • 但如果两个字典中的值相同,它会为 targetFlagqualifierFlag 创建一个值而不是两个值。有什么办法可以避免这种情况吗?
    猜你喜欢
    • 2020-08-20
    • 2018-06-26
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    相关资源
    最近更新 更多