Kaip sukurti generatoriaus numpy masyvą?

Kaip galėčiau sukurti generatoriaus objekto numpy masyvą?

Leiskite man paaiškinti problemą:

 >>> import numpy >>> def gimme(): ... for x in xrange(10): ... yield x ... >>> gimme() <generator object at 0x28a1758> >>> list(gimme()) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> numpy.array(xrange(10)) array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> numpy.array(gimme()) array(<generator object at 0x28a1758>, dtype=object) >>> numpy.array(list(gimme())) array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 

Šiuo atveju „gimme“ () yra generatorius, kurio išvestis norėčiau paversti masyvu. Tačiau masyvo konstruktorius nenaudoja generatoriaus, jis tiesiog saugo generatorių. Noriu elgtis numpy.array (sąrašas (gimme ())), bet nenoriu mokėti už atminties išlaidas, tuo pačiu metu turėdamas tarpinį sąrašą ir galutinį matricą. Ar yra ekonomiškesnis būdas?

117
15 дек. nustatykite saffsd 15 d. 2008-12-15 08:44 '08 8:44 2008-12-15 08:44
@ 4 atsakymai

Nelygios matricos reikalauja, kad jų ilgis būtų aiškiai nurodytas kūrimo metu, kitaip nei python sąrašai. Tai būtina, kad kiekvienam elementui skirtą erdvę būtų galima nuosekliai paskirstyti atmintyje. Sekvencinis pasiskirstymas yra esminis numpy masyvų bruožas: tai derinama su įmontuotu kodo įgyvendinimu, jei operacijos atliekamos daug greičiau nei įprastiniai sąrašai.

Turint tai omenyje, techniškai neįmanoma priimti generatoriaus objekto ir perjungti jį į masyvą, jei taip pat:

  • gali prognozuoti, kiek elementų ji bus pateikta paleidus:

     my_array = numpy.empty(predict_length()) for i, el in enumerate(gimme()): my_array[i] = el 
  • pasiruošę saugoti elementus tarpiniame sąraše:

     my_array = numpy.array(list(gimme())) 
  • gali sukurti du identiškus generatorius, paleiskite pirmąjį, kad rastumėte bendrą ilgį, inicijuotumėte masyvą ir tada iš naujo paleiskite generatorių, kad surastumėte kiekvieną elementą:

     length = sum(1 for el in gimme()) my_array = numpy.empty(length) for i, el in enumerate(gimme()): my_array[i] = el 

1 - tai tikriausiai tai, ko ieškote. 2 yra neveiksmingas ir 3 yra neveiksmingas (jums reikia du kartus pereiti per generatorių).

101
15 дек. atsakymas suteiktas 15 d. 2008-12-15 09:31 '08 9:31 val. 2008-12-15 09:31

Vienas „Google“ už šio „stackoverflow“ rezultato, aš rasiu, kad yra numpy.fromiter(data, dtype, count) . Pagal nutylėjimą, count=-1 suranda visus elementus iš iterable. Tam reikia, kad dtype būtų įdiegta aiškiai. Mano atveju jis dirbo:

border=0

numpy.fromiter(something.generate(from_this_input), float)

155
24 февр. atsakymas dhill 24 vasaris 2009-02-24 06:53 '09, 6:53 am. 2009-02-24 06:53

Šiek tiek tangentinis, bet jei jūsų generatorius supranta sąrašą, galite naudoti numpy.where kad gautumėte rezultatą efektyviau (po to, kai peržiūrėjau šį pranešimą)

5
12 мая '09 в 23:33 2009-05-12 23:33 Atsakymą pateikė Benjaminas Horstmanas gegužės 12 d., 09:33 23:33 2009-05-12 23:33

Nors galite sukurti 1D masyvą iš generatoriaus, naudodami numpy.fromiter() , galite numpy.fromiter() ND masyvą iš generatoriaus, naudodami numpy.stack :

 >>> mygen = (np.ones((5, 3)) for _ in range(10)) >>> x = numpy.stack(mygen) >>> x.shape (10, 5, 3) 

Jis taip pat veikia 1D masyvams:

 >>> numpy.stack(2*i for i in range(10)) array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]) 

Atkreipkite dėmesį, kad numpy.stack viduje sunaudoja generatorių ir sukuria tarpinį sąrašą su arrays = [asanyarray(arr) for arr in arrays] . Įgyvendinimą galima rasti čia .

3
31 авг. atsakymas pateikiamas mdeff 31 d. 2017-08-31 14:33 '17, 14:33 pm 2017-08-31 14:33

Kiti klausimai apie žymes „ arba „ Užduoti klausimą“