Vra

Ek is net begin met NumPy so ek mag word vermis'n paar kern konsepte...

Wat is die beste manier om te skep'n NumPy skikking van'n woordeboek wie se waardes is lyste?

Iets soos hierdie:

d = { 1: [10,20,30] , 2: [50,60], 3: [100,200,300,400,500] }

Moet draai in iets soos:

data = [
  [10,20,30,?,?],
  [50,60,?,?,?],
  [100,200,300,400,500]
]

Ek gaan om te doen'n paar basiese statistiek oor elke ry, bv.:

deviations = numpy.std(data, axis=1)

Vrae:

  • Wat is die beste / mees doeltreffende manier om te skep om die numpy.skikking van die woordeboek?Die woordeboek is groot;'n paar miljoen sleutels, elk met ~20 items.

  • Die aantal waardes vir elke'ry'is anders.As ek reg verstaan numpy wil eenvormige grootte, so wat doen ek vul in na die vermiste items te maak std() gelukkig?

Update:Een ding wat ek vergeet om te noem - terwyl die python tegnieke is redelike (bv.herhaling oor'n paar miljoen items is vinnig), dit is beperk tot'n enkele CPU.Numpy bedrywighede skaal mooi na die hardeware en druk al die CPUs, so hulle is aantreklik.

Was dit nuttig?

Oplossing

Jy hoef nie te skep numpy skikkings te noem numpy.std().Jy kan bel numpy.std() in'n lus oor al die waardes van jou woordeboek.Die lys sal omgeskakel word na'n numpy skikking op die vlieg te bereken die standaard variasie.

Die nadeel van hierdie metode is dat die belangrikste lus sal wees in python en nie in C.Maar ek dink dit moet vinnig genoeg wees:jy sal nog steeds bereken std by C spoed, en jy sal red van'n baie van die geheue soos jy sal nie hoef te stoor 0 waardes waar jy veranderlike grootte skikkings.

  • As jy wil om verder te optimaliseer hierdie, jy kan stoor jou waardes in'n lys van numpy skikkings, so dat jy nie die python lys -> numpy verskeidenheid omsetting net een keer.
  • as jy vind dat dit is nog steeds te stadig, probeer om te gebruik psigo te optimaliseer die python lus.
  • as dit is nog steeds te stadig, probeer om met behulp van Cython saam met die numpy module.Hierdie Handleiding eise indrukwekkende spoed verbeteringe vir die beeld verwerking.Of eenvoudig program die hele std funksie in Cython (sien hierdie vir maatstawwe en voorbeelde met som funksie )
  • 'n alternatief te Cython sou wees om te gebruik SLUK met numpy.ek.
  • as jy wil om te gebruik net numpy en het alles bereken op C-vlak, probeer om die groepering van al die rekords van dieselfde grootte saam in verskillende skikkings en noem numpy.std() op elkeen van hulle.Dit moet lyk soos die volgende voorbeeld.

voorbeeld met O(N) kompleksiteit:

import numpy
list_size_1 = []
list_size_2 = []
for row in data.itervalues():
    if len(row) == 1:
      list_size_1.append(row)
    elif len(row) == 2:
      list_size_2.append(row)
list_size_1 = numpy.array(list_size_1)
list_size_2 = numpy.array(list_size_2)
std_1 = numpy.std(list_size_1, axis = 1)
std_2 = numpy.std(list_size_2, axis = 1)

Ander wenke

Terwyl daar is reeds'n paar mooi redelike idees wat hier teenwoordig is, ek glo volgende is die moeite werd om te noem.

Vul die ontbrekende data met enige standaard waarde sou bederf die statistiese eienskappe (std, ens).Klaarblyklik is dit hoekom Mapad voorgestel dat die mooi truuk met die groepering van dieselfde grootte rekords.Die probleem met dit (die veronderstelling dat daar is nie'n a priori data op rekords lengtes is op die hand) is dat dit behels selfs meer berekeninge as die eenvoudige oplossing:

  1. ten minste O(N*logN) 'len se oproepe en vergelykings vir die sorteer met'n doeltreffende algoritme
  2. O(N) tjeks op die tweede manier is deur middel van die lys te bekom groepe(hul begin en die einde van die indekse op die " vertikale'as)

Met behulp van Psyco is'n goeie idee (dit is opvallend maklik om te gebruik, so seker wees om te gee dit'n probeer).

Dit blyk dat die optimale manier is om te neem die strategie beskryf deur Mapad in koeël #1, maar met'n verandering - nie te genereer die hele lys, maar itereer deur die woordeboek omskakeling van elke ry in numpy.verskeidenheid en die verrigting van die nodige berekeninge.Soos hierdie:

for row in data.itervalues():
    np_row = numpy.array(row)    
    this_row_std = numpy.std(np_row)
    # compute any other statistic descriptors needed and then save to some list

In elk geval'n paar miljoen loops in python sal nie so lank as wat mens sou verwag.Behalwe dit lyk nie soos'n roetine berekening, so wie gee as wat dit neem ekstra tweede/minuut as dit is hardloop een keer in'n rukkie, of selfs net een keer.


'n algemene variant van wat is voorgestel deur Mapad:

from numpy import array, mean, std

def get_statistical_descriptors(a):
    if ax = len(shape(a))-1
    functions = [mean, std]
    return f(a, axis = ax) for f in functions


def process_long_list_stats(data):
    import numpy

    groups = {}

    for key, row in data.iteritems():
        size = len(row)
        try:
            groups[size].append(key)
        except KeyError:
            groups[size] = ([key])

    results = []

    for gr_keys in groups.itervalues():             
        gr_rows = numpy.array([data[k] for k in gr_keys])       
        stats = get_statistical_descriptors(gr_rows)                
        results.extend( zip(gr_keys, zip(*stats)) )

    return dict(results)

numpy woordeboek

Jy kan gebruik maak van'n gestruktureerde skikking om die behoud van die vermoë om aan te spreek'n numpy voorwerp deur'n sleutel, soos'n woordeboek.

import numpy as np


dd = {'a':1,'b':2,'c':3}
dtype = eval('[' + ','.join(["('%s', float)" % key for key in dd.keys()]) + ']')
values = [tuple(dd.values())]
numpy_dict = np.array(values, dtype=dtype)

numpy_dict['c']

sal nou uitset

array([ 3.])
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top