Numpy: ndarray harus berasal dari collections.abc.Sequence?

Dibuat pada 1 Des 2012  ·  49Komentar  ·  Sumber: numpy/numpy

@juliantaylor mengangkat ini dalam masalah panda.

Contoh dari tiket:

import numpy as np
import random
random.sample(np.array([1,2,3]),1)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user1/py33/lib/python3.3/random.py", line 298, in sample
    raise TypeError("Population must be a sequence or set.  For dicts, use list(d).")
TypeError: Population must be a sequence or set.  For dicts, use list(d).

Ini terjadi pada 3.3 dengan 1.7.0rc1.dev-3a52aa0, dan di 3.2 dengan 1.6.2.
2.7 tentu saja tidak terpengaruh.

Kode yang relevan dari cpython / Lib / random.py: 297

from collections.abc import Set as _Set, Sequence as _Sequence
def sample(self, population, k):
# ...
    if not isinstance(population, _Sequence):
        raise TypeError("Population must be a sequence or set.  For dicts, use list(d).")

Saya tidak bisa grep lokasi lain di stdlib dengan tes serupa, tetapi lib2to3
memang menunjukkan kesetaraan yang diasumsikan:

lib2to3/fixes/fix_operator.py
5:operator.isSequenceType(obj)   -> isinstance(obj, collections.Sequence)

di 2.7

In [6]: operator.isSequenceType(np.array([1]))
Out[6]: True

tetapi di 3.3 / 3.2

>>> isinstance(np.array([1]), collections.Sequence)
False

Komentar yang paling membantu

Ya, cukup tambahkan Sequence.register(np.ndarray) suatu tempat.

Semua 49 komentar

Python 3.x hanya melakukan pemeriksaan yang lebih ketat di random.sample daripada Python 2.x. Pada 2.x numpy juga bukan merupakan subkelas Urutan (ndarray tidak memiliki metode index , count atau __reversed__ ). Jadi saya pikir Anda dapat menganggap ini sebagai salah penggunaan random.sample atau pemutusan kompatibilitas mundur oleh Python 3.x.

Cukup adil, tapi bisa dikatakan, kita bisa dengan mudah _membuat_menarik Urutan,
karena semua metode tersebut masuk akal dan akan langsung
melaksanakan. Sebenarnya hanya mewarisinya saja sudah cukup, karena Sequence
menyediakan semua metode yang hilang sebagai mixin.
Pada 2 Des 2012 13:30, "Ralf Gommers" [email protected] menulis:

Python 3.x hanya melakukan pemeriksaan yang lebih ketat secara random.sample daripada
Python 2.x. Pada 2.x numpy juga bukan subclass Sequence (ndarray tidak memiliki
indeks, hitung atau metode terbalik ). Jadi saya pikir Anda dapat menganggap ini sebagai
baik salah penggunaan random.sample atau kompatibilitas mundur oleh
Python 3.x.

-
Balas email ini secara langsung atau lihat di Gi tHubhttps: //github.com/numpy/numpy/issues/2776#issuecomment -10929601.

Saya akan mengatakan hal yang sama, jika bukan karena contoh 2to3 yang membuatnya lebih halus.
indeks dan hitungan tidak diperlukan Saya yakin: Tautan ,
Semua metode abstrak untuk Sequence sudah diimplementasikan, Yang lain memiliki implementasi default.

Masalahnya adalah bahwa MutableSequence sebenarnya lebih tepat, dan insert tidak diterapkan.

jangan lupa larik 0-d, saya tidak yakin apa yang terjadi dengan mereka sekarang, tetapi mereka sebenarnya bukan Urutan, bukan?

Hmm, Sequence dimaksudkan untuk objek tetap, beberapa metode MutableSequence (memperpanjang, pop) tidak masuk akal. Jadi ya, kita bisa menambahkan 3 metode itu tetapi rasanya kurang tepat.

Menurut saya, sebenarnya tidak ada alasan untuk random.sample membutuhkan instance Sequence .

__setitem__ diterapkan, tetapi bukan __delitem__ , jadi mungkin SomewhatMutableSequence ?

Masuk akal jika Anda menafsirkan antarmuka sebagai "urutan harus memiliki semua ini, tetapi beberapa mungkin
memiliki O () "yang buruk, itulah sebabnya mereka menawarkan implementasi naif dari beberapa metode.
Tentunya bukan semantik insert , pop yang tidak jelas dalam konteks ndarray.
Saya tidak yakin apa hal yang benar tentang iterasi melalui larik 0-d.
Seseorang dapat berargumen bahwa menawarkan metode __iter__ yang hanya menghasilkan TypeError daripada
StopIteration adalah pelanggaran mengetik bebek.

edit : Meskipun saya yakin itu bukan keputusan yang ceroboh.

ndarray bisa saja menjadi Sequence, itu tidak berarti itu harus tetap.

Btw. implementasi daftar CPython juga tidak mendukung penyisipan, pop, dan perluasan yang efisien tetapi masih berupa MutableSequence

ndarray tidak dapat mendukung penyisipan / pop / perluasan di tempat (ndarray memiliki ukuran tetap), jadi meskipun ini adalah urutan yang bisa berubah, ini bukan Python MutableSequence (dan tidak akan pernah). Ini dapat dan harus mendukung antarmuka Sequence .

Akan lebih baik jika random.sample tidak memeriksa ini, tetapi jika dilihat lebih dekat, ini memang memiliki alasan yang masuk akal - ini memiliki sejumlah implementasi berbeda untuk berbagai jenis argumen input, jadi perlu beberapa cara untuk membedakannya. Itu tidak bisa hanya mulai mengindeks dan berharap yang terbaik. Mungkin kita bisa melaporkan bug dan mencoba dan meyakinkan mereka untuk kembali ke implementasi sequence secara default untuk tipe yang tidak dikenali, tapi yang paling awal yang bisa membantu adalah 3.4 ...

Poin tentang array 0-d bagus, meskipun; Array 0-d tidak mendukung antarmuka Sequence (bahkan bukan Iterable ). Tetapi untuk tujuan Python, tidak terlalu buruk jika mereka berbohong tentang menjadi Sequence s dan kemudian menunggu akses sebenarnya untuk memunculkan kesalahan - mengetik bebek berarti Anda selalu bisa gagal jika Anda mau :-). Mungkin entah bagaimana caranya untuk membuat isinstance(a, Sequence) berhasil untuk array multidimensi dan gagal untuk array 0-d; jika kita bisa mewujudkannya maka keren. Tetapi bahkan jika kita tidak dapat melakukan hal terbaik untuk dilakukan adalah membuat ndarray's menjadi Sequence s.

Perhatikan bahwa MaskedArray sudah memiliki metode count , jadi menambahkan satu di ndarray yang melakukan sesuatu yang berbeda akan merusaknya.

Array 0-D lebih baik dianggap sebagai skalar dengan beberapa metode praktis (setidaknya begitulah pendapat saya tentang mereka); selain tidak dapat berulang, mereka juga tidak dapat diindeks yang bahkan lebih aneh jika Anda menganggapnya sebagai array. Jadi membuat array 0-D tidak konsisten dengan cara lain bukanlah masalah besar.

@ njsmith di mana Anda melihat beberapa implementasi? Setelah pemeriksaan isinstance (Urutan) saya hanya melihat len(population) dan kemudian konversi ke daftar. http://hg.python.org/cpython/file/22d891a2d533/Lib/random.py

Seri Pandas dan jenis DataFrame juga memiliki metode penghitungan yang tidak kompatibel, dan atribut indeks.

@rgommers : Hmm, Anda benar, saya disesatkan oleh pesan kesalahan, dan berpikir bahwa itu juga menerima bilangan bulat sebagai singkatan untuk range() , yang ternyata tidak. Meski begitu, mereka ingin mendefinisikan perilaku yang berbeda untuk set, urutan, dan pemetaan. Mungkin kita bisa meyakinkan mereka bahwa mereka harus mengalihkannya

if isinstance(population, _Set):
    population = tuple(population)
if isinstance(population, _Mapping):
    raise Blarrrgh()
# Otherwise assume that we have a sequence and hope

Itu juga poin bagus tentang subkelas ndarray yang ada. Sepertinya tidak ada cara untuk mengatakan bahwa ndarray adalah Sequence tetapi subkelasnya bukan :-(. Jadi opsi mana yang paling tidak buruk, mengingat beberapa subkelas ini tidak dapat memenuhi Sequence antarmuka tanpa merusak kompatibilitas?

  • Hentikan penggunaan yang tidak kompatibel dalam subkelas ndarray, dan akhirnya hapus dan ganti dengan Sequence versi yang kompatibel. Ini tampaknya bisa dilakukan untuk metode count , tetapi mengubah nama Series.index akan sangat mengganggu bagi orang-orang panda. (DataFrame bukan subclass dari ndarray jadi secara teknis itu tidak relevan, kecuali saya kira Seri dan DataFrame harus tetap sinkron.) Saya kira kita bisa bertanya @wesm apa yang dia pikirkan tapi ...
  • Lanjutkan dan deklarasikan ndarray dan subkelasnya untuk memenuhi definisi Sequence , dan terima bahwa untuk beberapa subkelas ndarray ini akan menjadi kebohongan. Hanya pada bagian yang jarang digunakan dari antarmuka Sequence , dan jenis Python biasanya terletak ...
  • Atur ulang hierarki warisan kita untuk memisahkan fungsionalitas dan omong kosong kelas dasar abstrak. Melakukan
class multidim_ndarray(ndarray, Sequence):
  pass

dan membuat instance array multi-redup dari kelas ini sebagai gantinya. Subkelas tidak terpengaruh karena mereka terus mewarisi dari ndarray , bukan multidim_ndarray . Tentu saja, satu objek ndarray dapat bertransisi antara 0-d dan multidimensi melalui .resize() ...

  • Terima bahwa ndarray tidak akan pernah menjadi Sequence .

[Hal isSequenceType adalah sedikit gangguan. Itu adalah fungsi lama yang mendahului keberadaan kelas dasar abstrak (yang ditambahkan di 2.6), dan bahkan tidak mencoba untuk memastikan antarmuka terperinci yang diperlukan dari urutan - itu hanya memeriksa bahwa tipe Anda (1) mendefinisikan __getitem__ , (2) bukan built-in dict . Jelas ini akan memberikan jawaban yang salah dalam banyak situasi (misalnya apa pun yang bertindak seperti dikt tapi bukan salah!). Jadi jika seseorang benar-benar menginginkan tipe urutan, maka isinstance(obj, Sequence) akan melakukan pekerjaan yang lebih baik, dan 2to3 melakukan hal yang benar. Tapi itu menimbulkan masalah untuk numpy ...]

Mungkin bisa meyakinkan orang-orang python untuk membuat kelas baru seperti SequenceBase yang bahkan di bawah Urutan dan tidak menjamin .index atau .count , tetapi hanya .__len__ dan __getitem__ atau semacamnya? Semuanya menyenangkan bahwa Urutan memiliki sesuatu seperti index , tetapi tampaknya agak aneh untuk memaksanya ke hal-hal seperti numpy dengan membuatnya menjadi urutan seperti hal-hal yang harus diketik bebek. Apakah orang python menyadari bahwa ini agak bermasalah?

Saya suka proposal @seberg; jika Python devs tidak setuju, saya akan memilih poin kedua dari @njsmith. Opsi yang hilang adalah hanya mengatakan bahwa ndarrays tidak memenuhi antarmuka Sequence. Tidak optimal, tapi lebih baik dari peluru 1 dan 3 imho.

[Ups, "opsi yang hilang" ada di sana sebagai opsi 4, entah mengapa parser penurunan harga memutuskan untuk melipatnya ke poin sebelumnya dengan cara yang membingungkan dan tidak terbaca. Saya telah mengedit komentar untuk memperbaiki pemformatannya.]

Separuh dari tipe yang didaftarkan dengan Sequence , yaitu buffer dan xrange , juga tidak memiliki metode ini. Tidak jelas bagi saya bahwa ini adalah metode antarmuka yang diperlukan serta metode kenyamanan bagi mereka yang menggunakan collections.Sequence sebagai kelas dasar / mixin.

@rkern : Tangkapan bagus. Jadi mungkin solusinya adalah menambahkan panggilan ke Sequence.register(np.ndarray) suatu tempat. (Ini juga akan menjadi solusi untuk reporter asli.)

Kita mungkin harus mengimplementasikan __reversed__ di beberapa titik juga ...

@rkern Anda benar, ini disebutkan sebagai terbitan terbuka di PEP: http://www.python.org/dev/peps/pep-3119/#sequences. Aneh bahwa PEP dengan status Final bahkan dapat memiliki masalah terbuka.

Menurut saya judul bug ini agak menyesatkan, karena bug tersebut tidak hanya ada di python3. Tentu, random.sample(numpy_array) berfungsi di python2, tetapi isinstance(np.array([1]), collections.Sequence) harus mengembalikan True dalam python apa pun> = 2.6.

Saya baru saja menemukan bug ini di Python 2.7 menggunakan modul autopep8. Secara default, ini mengubah beberapa panggilan operator.isSequenceType () menjadi isinstance (x, collections.Sequence). Tes akan menjadi False saat saya lulus numpy.ndarray. Ini bisa menjadi bug yang sangat licik.

Baru saja menemukannya juga dengan Python 2.7, menggunakan modul python-pillow. Image.point (lut, mode) memanggil isinstance (lut, collections.Sequence), versi sebelumnya menggunakan operator.isSequenceType ()

Sekarang mungkin saat yang tepat untuk mengunjungi kembali ini karena jenis skalar numerik numpy terdaftar (# 4547),

Jadi mungkin solusinya hanya dengan menambahkan panggilan ke Sequence.register (np.ndarray) di suatu tempat.

Ya, itu kompromi yang bagus.

Ya, cukup tambahkan Sequence.register(np.ndarray) suatu tempat.

@mitar ada yang berminat mengirimkan PR?

Tentu. Kemana ini harus pergi? Di file yang sama di mana np.ndarray dibuat?

Hanya untuk memastikan kami benar-benar berpikir ini adalah ide yang bagus: kami baru saja menambahkan penghentian untuk array kosong menjadi False (# 9718), yaitu, kami menghapus salah satu hal yang berfungsi untuk urutan) . Meskipun membaca komentar saya pikir kesimpulannya adalah bahwa skalar array tidak akan berfungsi, jadi saya kira array kosong dapat menjadi bagian dari janji yang ingkar ...

Untuk referensi di masa mendatang, tempat yang tepat untuk melakukan ini mungkin di numpy.core.multiarray :
https://github.com/numpy/numpy/blob/4f1541e1cb68beb3049a21cbdec6e3d30c2afbbb/numpy/core/multiarray.py

OK saya mau ini. Bagaimana? Ini akan menjadi bagaimana saya menerapkannya sebagai metode:

def __reversed__(self):
    return iter(self[::-1])

def index(self, value) -> int:
    return np.in1d(self, value).nonzero()[0]

def count(self, value) -> int:
    return (self == value).sum()

# Necessary due to lack of __subclasshook__
collections.abc.register(np.ndarray)

Kami menemukan bahwa dengan versi terbaru Tensorflow (2.0), memiliki Sequence.register(np.ndarray) membuat Tensorflow tidak berfungsi dengan baik. Tampaknya itu memeriksa di suatu tempat apakah nilai adalah urutan dan kemudian menggunakan berbeda dari jika itu adalah ndarray.

Lihat: https://gitlab.com/datadrivendiscovery/d3m/issues/426

Kocak. Saya cukup yakin menguji apakah sesuatu adalah sebuah array adalah ide yang lebih baik, karena itu hampir selalu akan menjadi kasus yang ditangani secara khusus.

Mungkin urutan pemeriksaan tipe salah, pertama-tama harus memeriksa ndarray, lalu urutan. Tetapi jika Anda pertama kali memeriksa urutannya, maka sekarang blok kode itu berjalan.

@mitar Kami sedang mempertimbangkan untuk menutup ini karena __contains__ / operator.in berperilaku berbeda (berulang, dan tidak untuk urutan), sehingga melanggar kontrak API. Apakah Anda memiliki kasus penggunaan untuk ini?

Bisakah Anda menguraikan kontrak API yang Anda pikirkan di sini. Saya tidak mengerti persis.

Contoh kasusnya adalah menulis kode umum yang mengetahui cara mengonversi di antara hal-hal, seperti jika Anda dapat mengulangi urutan dan mendapatkan kembali dimensi dengan diensi, lalu mengulang. Kemudian saya dapat mengonversi daftar daftar dengan cara yang sama seperti ndarray 2d, tetapi dapat menggeneralisasi ke beberapa dimensi dan seterusnya. Dan saya tidak perlu memeriksa lebih dari sekedar urutan.

Seperti disebutkan, ada beberapa masalah dengan melihat array sebagai urutan python bersarang. __contains__ adalah yang paling jelas, yang lainnya adalah bahwa array 0-D jelas bukan urutan bersarang. Juga kehalusan, seperti ada dimensi panjang 0, dan umumnya arr[0] = 0 tidak berarti bahwa arr[0] == 0 , karena arr[0] dapat berupa larik arbitrer itu sendiri (yang akan lebih baik dieja sebagai arr[0, ...] . Secara pribadi, menurut saya interpretasi "urutan bersarang" bagus, tetapi kurang berguna dari yang kita kira. (Ie saya jarang mengulang array sebagai for col in array dan bahkan jika saya melakukannya, saya tidak keberatan menulis for col in array.iter(axis=0)

Jadi saya cenderung melihat "array adalah urutan" sebagai analogi yang sedikit bermasalah (yang tidak berarti bahwa itu tidak bisa uesful, saya akui).
Namun, apa pun kasus penggunaannya, saya ingin tahu apakah tidak lebih baik jika menjelajahi ABC baru, seperti "ElementwiseContainer" baru. Satu yang juga memberi tahu pengguna bahwa + dan == , dll. Akan bekerja pada setiap elemen , dan bahwa, tidak seperti urutan Python, mereka seharusnya tidak mengharapkan + untuk digabungkan ( ya + bukan bagian dari Sequence ABC, tapi terasa alami di Python).

Hanya lewat -
Saya menulis ke Python-ideas minggu lalu karena saya mencatat bahwa Python collections.abc.Sequence tidak mengimplementasikan __eq__ dan perbandingan lainnya - meskipun ia memiliki semua metode lain untuk mengimplementasikannya agar Sequence berperilaku seperti daftar dan tupel. (utas email itu membawa saya ke masalah ini).

Saya mengusulkan untuk menambahkan __eq__ sana, tetapi itu jelas akan membuat urutan itu berbeda dari perilaku yang dimiliki Numpy.array.

Bagaimana dengan memformalkan lebih lanjut, dengan Python, apa itu "Urutan" dan kemudian mendelegasikan hal-hal ini yang akan menyimpang sebagai kasus khusus - sampai menambahkan collections.abc.ComparableSequence sana? (dan karena + untuk pembatalan disebutkan di atas, mungkin beberapa nama lain yang akan menyiratkan "urutan yang hasil perbandingannya dalam satu bool, dan berperilaku sebagai skalar untuk penggabungan dan dikalikan dengan skalar" - yaitu - perilaku Python untuk + dan * dalam daftar dan tupel). Oleh karena itu, spesifikasi pada Sequence dapat diformalkan sedemikian rupa sehingga setidaknya array numpy 1D akan sama persis.

Formalisasi tentang Python Sequence ini juga dapat membantu dengan divergensi lainnya, seperti yang disebutkan di https://github.com/numpy/numpy/issues/2776#issuecomment -330865166 di atas.

Saya tidak merasa cukup termotivasi untuk menempuh jalan itu sendirian - tetapi jika ini masuk akal, saya akan dengan senang hati membantu menulis PEP dan membantu mendorongnya. (Saya hanya ingin memeriksa mengapa sequence tidak menghasilkan __eq__ , dan mungkin memiliki PR untuk itu ketika saya membahasnya)

@jsbueno Masalah saya adalah bahwa saya tidak benar-benar melihat tambahan apa, atau di antara definisi yang sebenarnya akan membantu pengguna ndarray . Yang terbaik yang dapat saya pikirkan adalah Collection yang memiliki count() dan index() , tetapi apakah itu berguna? Yang lainnya akan menjadi ABC untuk hal-hal yang Python sendiri memiliki sedikit atau tidak memiliki konsep.

Saya pikir SymPy sebenarnya lebih tepat. Ini mengulang melalui semua elemen matriksnya, yang setidaknya membuatnya menjadi Collection .
Sekarang, saya ragu kita bisa berbuat banyak tentang itu, dan saya bahkan tidak yakin bahwa iterasi SymPy dari semua elemen sangat berguna (dan intuitif), tetapi setidaknya iterasi semua elemen konsisten dengan __contains__ . Perhatikan bahwa ini juga berarti bahwa len(Matrix) adalah jumlah elemen, dan _not_ Matrix.shape[0] !

Dengan risiko pengulangan banyak dari atas, selain dari array 1-D, apa itu array numpy ?:

  • Container : dari elemen: heavy_check_mark:
  • Sized + Iterable subarray (jika bukan 1-D): pertanyaan:
  • Reversible : kami bisa menerapkannya saja, jangan khawatir. :pertanyaan:
  • count() dan index() : dapat diimplementasikan untuk elemen (: heavy_check_mark :)
  • Sequence : Ketidaksesuaian antara subarray iterable dan wadah elemen : x:

Jadi, bahkan beberapa properti yang paling mendasar bentrok. NumPy bisa menjadi Container yang tahu bagaimana melakukan .index() dan .count() , yaitu Sequence tetapi tanpa bagian Iterable . Meskipun secara independen merupakan Iterable , tetapi subarray .
Dan jika itu tampak seperti kekacauan yang membingungkan, maka saya setuju, tetapi saya pikir itu memang sengaja. Satu-satunya solusi yang benar adalah pergi ke jalur SymPy atau tidak menjadi Iterable untuk memulai. (kita tidak bisa pergi ke jalur SymPy, dan saya ragu menghentikan __iter__ memiliki peluang.)

Secara pribadi, harapan saya adalah bahwa selain array 1-D, suka array hanyalah binatang yang sangat berbeda dibandingkan dengan Python Collections. Saat mempertimbangkan perilaku iterasi, Anda memerlukan MultidimensionalCollection untuk secara khusus memberi sinyal ketidakcocokan antara __contains__ dan __iter__ (tetapi apakah itu berguna?).

Ketika melihat di luar apa yang saat ini didefinisikan oleh Sequence , saya akan menyatakan kembali bahwa menurut saya ElementwiseCollection (operator adalah operator elementwise daripada operator kontainer, misalnya + ) adalah yang paling banyak mendefinisikan karakteristik dari array numpy dan semua seperti array secara umum (lihat pemrograman array). Ini juga merupakan konsep yang sama sekali asing bagi - dan terkadang bertentangan dengan - Python itu sendiri.

Satu-satunya hal adalah menandai larik satu dimensi, dan hanya larik satu dimensi sebagai urutan, karena mereka tidak memiliki ketidakcocokan subarray vs. elemen. Pada titik mana, ya, __eq__ tentu saja tidak ditentukan untuk mereka, dan __nonzero__ tidak didefinisikan serupa dengan urutan python pada umumnya.

Terima kasih atas tanggapannya, dan saya minta maaf lagi karena telah terjun dalam gerbong selama 8 tahun di sini. Dengan komentar Anda, beberapa jam setelah pertukaran e-mail terakhir, dan mengobrol dengan teman lain di tengah-tengah, saya setuju sebagian besar hal ini lebih baik dibiarkan begitu saja. Suatu saat di masa depan Python dapat memilih untuk memiliki definisi Urutan yang lebih formal daripada "koleksi apa pun.abc.Sequence diimplementasikan sekarang".

Saya hanya akan menambahkan, setelah membaca komentar Anda di atas, bahwa menurut saya karakteristik yang Anda cantumkan sebagai "apa yang membuat Urutan Python" tidak memiliki fitur terpenting yang membuat ndarrays menyerupai urutan seperti daftar dan tupel bagi saya: memiliki indeks- ruang yang dapat menangani semua elemen individu. Tapi saya tidak berpikir memformalkan abc untuk itu akan menjadi nilai praktis apa pun, baik dalam pengkodean atau dalam petunjuk tipe statis.

@seberg Itu sinopsis yang bagus.

Masalah ini sepertinya tentang penggunaan ndarray dalam konteks yang mengharapkan Sequence atau Iterable atau Container . Pendekatan sederhana adalah memiliki anggota dengan ndarray yang mengekspos tampilan murah yang menjanjikan dan menyediakan antarmuka yang sesuai dan menanggapi cek isinstance . Sebagai contoh:

class ndarray(Generic[T]):
    def as_container(self) -> Container[T]:
        if self.ndim == 0:
            raise ValueError
        return ContainerView(self)  # correctly answers __len__, __iter__ etc.
    def as_subarray_iterable(self) -> Iterable[np.ndarray[T]]:
        if self.ndim <= 1:
            raise ValueError
        return SubarrayIterableView(self)
    def as_scalar_sequence(self) -> Sequence[T]:
        if self.ndim != 1:
            raise ValueError
        return ScalarView(self)
    def as_subarray_sequence(self) -> Sequence[np.ndarray[T]]:
        if self.ndim <= 1:
            raise ValueError
        return SubarraySequenceView(self)  # this view has to reinterpret __contains__ to do the expected thing.

Alih-alih ndarray menjanjikan untuk menjadi segalanya bagi semua orang, pengguna meminta apa yang dia butuhkan, dan jika ndarray dapat menyediakannya, ia melakukannya dengan cara yang semurah mungkin. Jika tidak bisa, itu menimbulkan pengecualian. Ini menyederhanakan kode pengguna dengan memindahkan cek ndim yang harus dilakukan pengguna (terutama saat menggunakan anotasi tipe) ke ndarray .

Haruskah anotasi terakhir itu Sequence dan bukan Iterable ?

@ eric-wieser Yup! Terima kasih. Apa yang kamu pikirkan

Nah, as_subarray_sequence bisa dibilang list(arr) :)

@ eric-wieser Ya, saya pikir akan lebih murah untuk memberikan tampilan, tapi saya tidak tahu.

Nah, list(arr) hanya menghasilkan len(arr) tampilan, yang pada akhirnya Anda akan tetap menghasilkan jika saya mengulanginya.

Saya masih berpikir kami terlalu fokus pada apa yang bisa dilakukan dan tidak cukup pada apa masalahnya saat ini. Secara khusus, semua metode yang Anda berikan di atas sangat mudah diterapkan jika Anda tahu bahwa Anda memiliki ndarray-like (saya tidak setuju bahwa array 0-D bukanlah container). Jadi mereka hanya akan berguna jika ada ABC standar untuk mereka, dan dalam kasus itu juga akan cukup untuk mendefinisikan bahwa pengindeksan dasar kompatibel numpy dan mungkin menyertakan properti .flat .

Masalah asli ( random.sample berhenti bekerja) tampaknya cukup tidak relevan karena waktu berlalu. Ya, ini agak mengganggu, tetapi mungkin bahkan lebih baik, karena pengguna mungkin mengharapkan subarray atau elemen yang akan dipilih.

Saya yakin kita memecahkan beberapa kode bebek-mengetik. Beberapa masalah mungkin terjadi dengan serialisasi (saya tidak memiliki contoh di tangan). Dan banyak dari kode tersebut tidak akan bermasalah dengan penggunaan isinstance cek pada ABC s, tetapi tidak suka memeriksa np.ndarray secara khusus. Saya tidak melihat bagaimana menambahkan metode ke ndarray akan membantu dengan itu, kita akan membutuhkan ABC , kemungkinan dengan sedikit lebih dari properti .ndim dan mungkin mengabadikan iterasi gaya urutan bersarang.

Metode seperti di atas mungkin masuk akal sebagai protokol konsumen untuk bekerja dengan semua jenis array, tetapi apakah itu masalah yang kita coba selesaikan :)? Mereka sepertinya tidak seperti urutan Python yang ingin diekspos.

@ eric-wieser

Anda benar tentu saja, tetapi Anda mungkin tidak mengulangi seluruh urutan. Anda mungkin hanya memilih beberapa elemen.

@beber

Saya masih berpikir kami terlalu fokus pada apa yang bisa dilakukan dan tidak cukup pada apa masalahnya saat ini

Saya setuju dengan kamu. Masalah apa yang Anda bayangkan? Saya membayangkan bahwa ketika numpy 1.10 keluar dengan tipe, saya terkadang ingin menggunakan numpy array satu dimensi sebagai urutan. Jika saya ingin melakukannya saat ini, saya perlu:

  • periksa apakah itu satu dimensi, dan
  • hubungi cast untuk memberi tahu mypy bahwa ini sebenarnya adalah urutan.

Itu sebabnya saya ingin memberikan metode untuk melakukan itu secara otomatis. Saya benci antarmuka yang besar juga, tetapi bagi saya metode atau fungsi kosong semacam ini akan menjadi lebih dan lebih lazim saat penjelasan jenis populer. Bagaimana menurut anda?

(Saya tidak setuju bahwa array 0-D bukanlah kontainer).

Saya tidak tahu, tapi saat ini Anda mengumpulkan __len__ untuk ini, jadi sepertinya mereka tidak bekerja seperti kontainer. Saya pikir akan sangat membantu bagi mypy untuk melaporkan kesalahan jika Anda meneruskan array 0-D ke fungsi yang menerima wadah. Itu tidak akan menangkap jika Anda membuat wadah array 0-D.

kita akan membutuhkan ABC baru, kemungkinan dengan sedikit lebih dari properti .ndim dan mungkin mengabadikan iterasi gaya urutan-bersarang.

Saya tidak ingin menambahkannya ke dalam saran saya, tetapi saya pikir ke sanalah tujuan Anda. Saya adalah pengguna setia perpustakaan JAX yang dirancang dengan luar biasa. Saya membayangkan bahwa di masa depan, numpy.ndarray dan jax.numpy.ndarray (yang memiliki subclass) keduanya akan mewarisi dari semacam abstrak NDArray . Anda bisa memiliki lebih dari ndim . Idealnya, setidaknya NDArray(Generic[T]) , dan mungkin acara memiliki bentuk atau jumlah dimensinya juga. Itu bisa memiliki __eq__ mengembalikan NDArray[np.bool_] . Anda mungkin lebih tahu dari saya :)

Beberapa tahun yang lalu, saya mencari masalah ini untuk menyarankan bahwa numpy.array harus mewarisi dari collections.Sequence , tetapi sekarang saya menemukan argumen (terutama milik Anda !!) di utas ini sangat meyakinkan. Array numpy bukanlah urutan yang sebenarnya, dan sepatu mereka sepertinya akan menyebabkan lebih banyak kerusakan daripada kebaikan. Mengapa tidak membiarkannya menjadi milik mereka, dan memaksa pengguna untuk secara eksplisit meminta antarmuka yang mereka inginkan?

Dan banyak dari kode tersebut tidak akan bermasalah dengan penggunaan pemeriksaan isinstance di ABC,

Sekarang setelah Anda menyebutkannya, mungkin semua metode yang saya usulkan seharusnya mengembalikan tampilan. Dengan begitu, mereka dapat menjawab pemeriksaan instans dengan benar.

Metode seperti di atas mungkin masuk akal sebagai protokol konsumen untuk bekerja dengan semua jenis array, tetapi apakah itu masalah yang kita coba selesaikan :)? Mereka sepertinya tidak seperti urutan Python yang ingin diekspos.

Saya sangat setuju bahwa jawaban untuk ini tergantung pada masalah yang kita coba selesaikan. Setelah mabuk jenis anotasi kool aid, saya tertarik untuk menulis kode numpy ringkas yang melewati mypy tanpa mengotori kode dengan # type: ignore . Masalah apa yang Anda pikirkan?

Nah, petunjuk ketik dan interop dengan objek lain yang mirip larik mungkin merupakan motivasi yang baik. Saya mungkin menyarankan untuk membuka masalah baru atau utas milis. Saat ini, saya tidak yakin apa yang terbaik untuk dipikirkan di sini, mengetik sedang terbentuk, jadi mungkin itu akan memperjelas beberapa hal.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat