简体   繁体   English

从字典列表中查找具有键最大值的唯一项

[英]Find unique item from list of dictionary with the maximum value of a key

I have this list of dictionary items and I need to find one item from each label with maximum width value.我有这个字典项目列表,我需要从每个 label 中找到一个具有最大宽度值的项目。

Input:输入:

[{'height': 32, 'label': '1', 'left': 944, 'top': 173, 'width': 17},
 {'height': 60, 'label': '1', 'left': 617, 'top': 276, 'width': 19},
 {'height': 43, 'label': '1', 'left': 508, 'top': 296, 'width': 19},
 {'height': 91, 'label': '3', 'left': 247, 'top': 194, 'width': 20},
 {'height': 94, 'label': '1', 'left': 114, 'top': 193, 'width': 22},
 {'height': 96, 'label': '4', 'left': 281, 'top': 185, 'width': 22},
 {'height': 51, 'label': '2', 'left': 486, 'top': 288, 'width': 23},
 {'height': 67, 'label': '2', 'left': 611, 'top': 142, 'width': 25},
 {'height': 42, 'label': '2', 'left': 919, 'top': 164, 'width': 25},
 {'height': 48, 'label': '3', 'left': 829, 'top': 165, 'width': 25},
 {'height': 73, 'label': '3', 'left': 363, 'top': 699, 'width': 25},
 {'height': 91, 'label': '1', 'left': 133, 'top': 192, 'width': 26},
 {'height': 95, 'label': '2', 'left': 102, 'top': 447, 'width': 26},
 {'height': 70, 'label': '5', 'left': 258, 'top': 610, 'width': 26},
 {'height': 97, 'label': '6', 'left': 164, 'top': 317, 'width': 27},
 {'height': 55, 'label': '4', 'left': 588, 'top': 283, 'width': 28},
 {'height': 65, 'label': '4', 'left': 379, 'top': 401, 'width': 28},
 {'height': 91, 'label': '4', 'left': 157, 'top': 193, 'width': 29},
 {'height': 96, 'label': '4', 'left': 186, 'top': 190, 'width': 29},
 {'height': 74, 'label': '4', 'left': 248, 'top': 339, 'width': 29},
 {'height': 60, 'label': '3', 'left': 422, 'top': 281, 'width': 29},
 {'height': 98, 'label': '1', 'left': 157, 'top': 445, 'width': 29},
 {'height': 106, 'label': '2', 'left': 211, 'top': 440, 'width': 29},
 {'height': 68, 'label': '6', 'left': 414, 'top': 398, 'width': 29}]

Expected output:预期 output:

[{'height': 98, 'label': '1', 'left': 157, 'top': 445, 'width': 29},
 {'height': 106, 'label': '2', 'left': 211, 'top': 440, 'width': 29},
 {'height': 60, 'label': '3', 'left': 422, 'top': 281, 'width': 29},
 {'height': 91, 'label': '4', 'left': 157, 'top': 193, 'width': 29},
 {'height': 70, 'label': '5', 'left': 258, 'top': 610, 'width': 26},
 {'height': 68, 'label': '6', 'left': 414, 'top': 398, 'width': 29}]
df = pd.DataFrame(my_list)

Casting everything to number:将所有内容转换为数字:

for col in df.columns:
    df[col] = pd.to_numeric(df[col])

Sort values by 'label' && 'width' -> ascending argument applies sorting rule based on index.按 'label' && 'width' 排序值 -> ascending参数应用基于索引的排序规则。 Then, keep only first record for each unique 'label' with drop_duplicates('label') :然后,使用drop_duplicates('label')仅保留每个唯一“标签”的第一条记录:

df.sort_values(['label','width'], ascending=[True, False]).drop_duplicates('label')

If you want to sort by another value, if is not in your df'colums you first have to create the column:如果您想按另一个值排序,如果不在您的 df'colums 中,您首先必须创建该列:

df['w2h'] = df['width'] * df['height']

Then, repeating sorting and transform to list of dicts:然后,重复排序和转换为字典列表:

df.sort_values(['label','w2h'], ascending=[True, False])\
    .drop_duplicates('label').to_dict('records')
df = pd.DataFrame(your_list)
output = df.sort_values(["label", "width"], ascending=[True, False]).drop_duplicates(
    subset="label"
).to_dict("records")

In output :output

[
    {"height": 98, "label": "1", "left": 157, "top": 445, "width": 29},
    {"height": 106, "label": "2", "left": 211, "top": 440, "width": 29},
    {"height": 60, "label": "3", "left": 422, "top": 281, "width": 29},
    {"height": 91, "label": "4", "left": 157, "top": 193, "width": 29},
    {"height": 70, "label": "5", "left": 258, "top": 610, "width": 26},
    {"height": 68, "label": "6", "left": 414, "top": 398, "width": 29},
]
data = [{'height': 32, 'label': '1', 'left': 944, 'top': 173, 'width': 17},
        {'height': 60, 'label': '1', 'left': 617, 'top': 276, 'width': 19},
        {'height': 43, 'label': '1', 'left': 508, 'top': 296, 'width': 19},
        {'height': 91, 'label': '3', 'left': 247, 'top': 194, 'width': 20},
        {'height': 94, 'label': '1', 'left': 114, 'top': 193, 'width': 22},
        {'height': 96, 'label': '4', 'left': 281, 'top': 185, 'width': 22},
        {'height': 51, 'label': '2', 'left': 486, 'top': 288, 'width': 23},
        {'height': 67, 'label': '2', 'left': 611, 'top': 142, 'width': 25},
        {'height': 42, 'label': '2', 'left': 919, 'top': 164, 'width': 25},
        {'height': 48, 'label': '3', 'left': 829, 'top': 165, 'width': 25},
        {'height': 73, 'label': '3', 'left': 363, 'top': 699, 'width': 25},
        {'height': 91, 'label': '1', 'left': 133, 'top': 192, 'width': 26},
        {'height': 95, 'label': '2', 'left': 102, 'top': 447, 'width': 26},
        {'height': 70, 'label': '5', 'left': 258, 'top': 610, 'width': 26},
        {'height': 97, 'label': '6', 'left': 164, 'top': 317, 'width': 27},
        {'height': 55, 'label': '4', 'left': 588, 'top': 283, 'width': 28},
        {'height': 65, 'label': '4', 'left': 379, 'top': 401, 'width': 28},
        {'height': 91, 'label': '4', 'left': 157, 'top': 193, 'width': 29},
        {'height': 96, 'label': '4', 'left': 186, 'top': 190, 'width': 29},
        {'height': 74, 'label': '4', 'left': 248, 'top': 339, 'width': 29},
        {'height': 60, 'label': '3', 'left': 422, 'top': 281, 'width': 29},
        {'height': 98, 'label': '1', 'left': 157, 'top': 445, 'width': 29},
        {'height': 106, 'label': '2', 'left': 211, 'top': 440, 'width': 29},
        {'height': 68, 'label': '6', 'left': 414, 'top': 398, 'width': 29}]
 
labels = ['1', '2', '3', '4', '5', '6']

answers = list()

# iterate over all labels
for label in labels:

    max_label_row = None  # initialize max label row
    max_label_value = 0

    
    # check entire dataset
    for row in data:
        # check if row has biggest value
        if row['label'] == label and row['width'] > max_label_value:
            max_label_value = row['width']
            max_label_row = row
    
    answers.append(max_label_row)
    
# print info
for row in answers:
    print(row)

Here is an example without pandas, hopefully so you can get a better understanding of the logic to go through and solve this problem.这里是一个没有 pandas 的例子,希望你可以通过这个例子更好地理解 go 的逻辑并解决这个问题。

Another example without Pandas, but leveraging some itertools:另一个没有 Pandas 的示例,但利用了一些 itertools:

from operator import itemgetter

data = [
    {'height': 32, 'label': '1', 'left': 944, 'top': 173, 'width': 17},
    {'height': 60, 'label': '1', 'left': 617, 'top': 276, 'width': 19},
    {'height': 43, 'label': '1', 'left': 508, 'top': 296, 'width': 19},
    {'height': 91, 'label': '3', 'left': 247, 'top': 194, 'width': 20},
    {'height': 94, 'label': '1', 'left': 114, 'top': 193, 'width': 22},
    {'height': 96, 'label': '4', 'left': 281, 'top': 185, 'width': 22},
    {'height': 51, 'label': '2', 'left': 486, 'top': 288, 'width': 23},
    {'height': 67, 'label': '2', 'left': 611, 'top': 142, 'width': 25},
    {'height': 42, 'label': '2', 'left': 919, 'top': 164, 'width': 25},
    {'height': 48, 'label': '3', 'left': 829, 'top': 165, 'width': 25},
    {'height': 73, 'label': '3', 'left': 363, 'top': 699, 'width': 25},
    {'height': 91, 'label': '1', 'left': 133, 'top': 192, 'width': 26},
    {'height': 95, 'label': '2', 'left': 102, 'top': 447, 'width': 26},
    {'height': 70, 'label': '5', 'left': 258, 'top': 610, 'width': 26},
    {'height': 97, 'label': '6', 'left': 164, 'top': 317, 'width': 27},
    {'height': 55, 'label': '4', 'left': 588, 'top': 283, 'width': 28},
    {'height': 65, 'label': '4', 'left': 379, 'top': 401, 'width': 28},
    {'height': 91, 'label': '4', 'left': 157, 'top': 193, 'width': 29},
    {'height': 96, 'label': '4', 'left': 186, 'top': 190, 'width': 29},
    {'height': 74, 'label': '4', 'left': 248, 'top': 339, 'width': 29},
    {'height': 60, 'label': '3', 'left': 422, 'top': 281, 'width': 29},
    {'height': 98, 'label': '1', 'left': 157, 'top': 445, 'width': 29},
    {'height': 106, 'label': '2', 'left': 211, 'top': 440, 'width': 29},
    {'height': 68, 'label': '6', 'left': 414, 'top': 398, 'width': 29}
]

ordered = sorted(data, key=itemgetter('label'))
grouped = groupby(ordered, key=itemgetter('label'))

for key, group in grouped:
    ordered_group = sorted(group, key=itemgetter('width'), reverse=True)
    print(ordered_group[0])

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

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