[Python] Hoe top x waardes in list met data object bepalen?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Topicstarter
Momenteel bezig met het verwerken van data objecten welke in een list[] zitten. Nu is het zo dat de data objecten een soortgelijke structuur hebben:

Python:
1
2
3
4
5
data[0] = {'pers_naam': 'Naam Persoon 1', 'pers_score': '+2', 'pers_functie': 'administratie'}
data[1] = {'pers_naam': 'Naam Persoon 2', 'pers_score': '+8', 'pers_functie': 'administratie'}
data[2] = {'pers_naam': 'Naam Persoon 3', 'pers_score': '0', 'pers_functie': 'voorbereiding'}
data[3] = {'pers_naam': 'Naam Persoon 4', 'pers_score': '-1', 'pers_functie': 'voorbereiding'}
....


Is het mogelijk om middels een max of andere functie de top 3, 4 of 5 waardes per functiegroep bij elkaar op te tellen?

Onderstaande geeft niet het gewenste resultaat. Hoe kan ik dit middels Python ondervangen?
Python:
1
2
for pers in data:
    max(pers.pers_score)


Is bovenstaande de juiste oplossing of dien ik hiervoor een aparte list samen te stellen met scores per functiegroep?

Acties:
  • 0 Henk 'm!

  • Nvidiot
  • Registratie: Mei 2003
  • Laatst online: 03-06 16:38

Nvidiot

notepad!

Ervoor zorgen dat je data objecten een __cmp__ hebben en dan sorted(data)[:5] gebruiken?

What a caterpillar calls the end, the rest of the world calls a butterfly. (Lao-Tze)


Acties:
  • 0 Henk 'm!

  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Topicstarter
Nvidiot schreef op dinsdag 02 oktober 2012 @ 14:07:
Ervoor zorgen dat je data objecten een __cmp__ hebben en dan sorted(data)[:5] gebruiken?
Is dat ook mogelijk op de volgende methode? Vanuit een for in wordt nu mijn data gevuld met records, te weten:

Python:
1
2
3
4
5
6
for person in lst_persons:
    data = {
        'pers_naam' : person.get('personname'),
        'pers_score' : person.get('score'), 
        'pers_functie' : ('Administratie' if person.get('id') > 100 else 'Voorbereiding')
    }

Hoe zorg ik er in dit geval dan voor dat ik de __cmp__ aan het object kan toevoegen? En daarbij, wat betekend in dit geval sorted(data)[:5]. Lees ik hiermee de top 5 uit of het 5e child object in de data collector?

Acties:
  • 0 Henk 'm!

  • MrHaas
  • Registratie: Maart 2009
  • Laatst online: 23-08 10:21
Gebruik het key argument in sorted:

Python:
1
sorted(data, key=lambda x: x['pers_score'])[:3]

[ Voor 30% gewijzigd door MrHaas op 02-10-2012 15:54 ]


Acties:
  • 0 Henk 'm!

  • Big4SMK
  • Registratie: September 2001
  • Laatst online: 09-09 11:37
Je moet een lijstje hebben van de (integer) waardes van pers_score, en die vervolgens sorten.

Python:
1
2
lijstje = [int(item['pers_score']) for item in data]
lijstje.sort()


vervolgens kan je de hoogste 3 selecteren met
Python:
1
lijstje[-3:]

[ Voor 4% gewijzigd door Big4SMK op 02-10-2012 15:54 ]


Acties:
  • 0 Henk 'm!

  • Nvidiot
  • Registratie: Mei 2003
  • Laatst online: 03-06 16:38

Nvidiot

notepad!

Je zou de key parameter kunnen gebruiken voor sorted:
Python:
1
sorted_data = sorted(data, key=lambda item: item['pers_score'])

[:5] is een list slice, vanaf het begin van de lijst en dan 5 entries, dus in het geval van een gesorteerde lijst, de top 5.

http://wiki.python.org/moin/HowTo/Sorting/#Key_Functions
http://stackoverflow.com/...for-python-slice-notation

What a caterpillar calls the end, the rest of the world calls a butterfly. (Lao-Tze)


Acties:
  • 0 Henk 'm!

  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Topicstarter
Helder, maar is het ook mogelijk om de resultaten van de top 1,2,3,4,5 in een soortement van matrix te plaatsen zodat dit per loop te gebruiken is of wordt dit uiteindelijk teveel rekenkracht om binnen een def te gaan uitwerken?

code:
1
2
3
Functie 1 2 3 4 5
Administratie 4 7 9 10 9
Uitvoering 3 6 8 8 7

Of krijg je hier uiteindelijk weer een dataset waarin dit te vatten is?

Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Dat kan met itertools.groupby. Eerst sorteren op (functie, score), en vervolgens doe je een groupby op functie:

Python:
1
2
3
4
5
6
7
8
9
import itertools
data = [{'pers_naam': 'Naam Persoon 1', 'pers_score': 2, 'pers_functie': 'administratie'},
        {'pers_naam': 'Naam Persoon 2', 'pers_score': 8, 'pers_functie': 'administratie'},
        {'pers_naam': 'Naam Persoon 3', 'pers_score': 0, 'pers_functie': 'voorbereiding'},
        {'pers_naam': 'Naam Persoon 4', 'pers_score': -1, 'pers_functie': 'voorbereiding'}]
data.sort(key=lambda x: (x['pers_functie'], x['pers_score']))

for functie, items in itertools.groupby(data, lambda x: x['pers_functie']):
    print functie, [(i['pers_naam'], i['pers_score']) for i in items]


dat geeft dan:

administratie [('Naam Persoon 1', 2), ('Naam Persoon 2', 8)]
voorbereiding [('Naam Persoon 4', -1), ('Naam Persoon 3', 0)]
Pagina: 1