Reputation: 39
I have this list of dictionary items and I need to find one item from each label with maximum width value.
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:
[{'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}]
Upvotes: 0
Views: 41
Reputation: 873
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. Then, keep only first record for each unique 'label' withdrop_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['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')
Upvotes: 1
Reputation: 1748
Another example without Pandas, but leveraging some 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])
Upvotes: 0
Reputation: 515
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.
Upvotes: 0
Reputation: 755
df = pd.DataFrame(your_list)
output = df.sort_values(["label", "width"], ascending=[True, False]).drop_duplicates(
subset="label"
).to_dict("records")
In 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},
]
Upvotes: 0