Python ve NumPy kullanan çok büyük matrisler


86

NumPy son derece kullanışlı bir kitaplıktır ve onu kullanarak, oldukça büyük (10000 x 10000) matrisleri kolayca işleyebildiğini, ancak çok daha büyük herhangi bir şeyle uğraşmaya başladığını (50000 x 50000 matris oluşturmaya çalışırken) buldum. başarısız). Açıkçası, bunun nedeni büyük bellek gereksinimleridir.

NumPy'de doğal olarak devasa matrisler yaratmanın bir yolu var mı (diyelim 1 milyon x 1 milyon) (birkaç terabayt RAM olmadan)?

Yanıtlar:


91

PyTables ve NumPy gitmenin yoludur.

PyTables, verileri isteğe bağlı sıkıştırma ile HDF formatında diskte depolar. Veri kümelerim genellikle 10x sıkıştırmaya sahip, bu da onlarca veya yüz milyonlarca satırla uğraşırken kullanışlıdır. Aynı zamanda çok hızlı; 5 yaşındaki dizüstü bilgisayarım, saniyede 1.000.000 satırda SQL benzeri GROUP BY toplama yaparak verileri sıkıştırabilir. Python tabanlı bir çözüm için fena değil!

Verilere tekrar NumPy yeniden dizilimi olarak erişmek şu kadar basittir:

data = table[row_from:row_to]

HDF kütüphanesi, ilgili veri parçalarını okumak ve NumPy'ye dönüştürmekle ilgilenir.


4
Yani yine de işlemek için verileri kendiniz parçalara ayırmanız gerekiyor? Bu sadece disk dosyalarına ve disk dosyalarından dönüştürmeyi basitleştirmenin bir yolu mu?
endolith

Cevabınızı biraz daha net ve bazı örneklerle genişletme şansınız var mı?
Adam B

56

numpy.arrays bellekte yaşamak içindir. RAM'inizden daha büyük matrislerle çalışmak istiyorsanız, bunun etrafında çalışmalısınız. Takip edebileceğiniz en az iki yaklaşım vardır:

  1. Matrislerinizin sahip olduğu herhangi bir özel yapıyı kullanan daha verimli bir matris gösterimini deneyin . Örneğin, diğerlerinin daha önce de belirttiği gibi, seyrek matrisler (çok sayıda sıfır içeren matrisler) için verimli veri yapıları vardır scipy.sparse.csc_matrix.
  2. Algoritmanızı alt matrisler üzerinde çalışacak şekilde değiştirin . Diskten yalnızca şu anda hesaplamalarda kullanılan matris bloklarını okuyabilirsiniz. Kümeler üzerinde çalışmak üzere tasarlanan algoritmalar, veriler farklı bilgisayarlara dağıtıldığı ve yalnızca ihtiyaç duyulduğunda iletildiği için genellikle blok halinde çalışır. Örneğin, matris çarpımı için Fox algoritması (PDF dosyası) .

4
3- Büyük Veri paradigmasına adım atın ve MapReduce gibi çözümleri inceleyin
Medeiros

2 numara için, parçalarınızı ne kadar büyük yapacağınıza nasıl karar verirsiniz? Boş bellek miktarını ölçmenin ve parçalarınızı buna göre boyutlandırmanın bir yolu var mı?
endolith

30

Diskteki bir dosyayı bellek eşlemek için numpy.memmap kullanabilmeniz gerekir. Daha yeni python ve 64 bit makine ile, her şeyi belleğe yüklemeden gerekli adres alanına sahip olmalısınız. İşletim sistemi, dosyanın yalnızca bir kısmını bellekte tutmalıdır.


19
Belleğe sığmayan bir şeyi yapmak için nasıl kullanılacağına dair bir örnek verebilir misiniz?
endolith

24

Seyrek matrisleri işlemek için scipy, üstüne oturan pakete ihtiyacınız var numpy- size veren seyrek matris seçenekleri hakkında daha fazla ayrıntı için buraya bakın scipy.


11

Stefano Borini'nin yazısı , bu tür işlerin halihazırda ne kadar ilerlediğine bakmamı sağladı.

Budur. Temelde istediğinizi yapıyor gibi görünüyor. HDF5, çok büyük veri kümelerini depolamanıza ve ardından NumPy'nin yaptığı gibi bunlara erişmenize ve bunları kullanmanıza izin verecektir.


9
PyTables daha iyi bir seçim olabilir. Çekirdek HDF5 işlevselliğinden daha yüksek düzeydedir (H5Py, Python'dan erişilebilen düşük düzeyli API'den biraz daha fazladır). Ayrıca geçen haftanın 2.2 beta sürümünde bu sorun için araçlar var: pytables.org/moin/ReleaseNotes/Release_2.2b1 Eklenen Expr, isteğe bağlı büyük boyutlarda çalışan ifadeleri ('3 * a + 4 * b' gibi) değerlendirebilen bir sınıf. kaynakları optimize ederken diziler [...]. Numexpr paketine benzer, ancak NumPy nesnelerine ek olarak, Array, CArray, EArray ve Column PyTables nesneleri gibi disk tabanlı homojen dizileri de kabul eder.
AFoglia

5

64 bit işletim sistemi ve Python / NumPy'nin 64 bit sürümünü kullandığınızdan emin olun. 32 bit mimarilerde tipik olarak 3 GB belleği ele alabileceğinizi unutmayın (bellek eşlemeli G / Ç vb. İçin yaklaşık 1 GB kaybedilir).

64-bit ve mevcut RAM'den daha büyük şeyler dizileri ile sanal bellekten kurtulabilirsiniz, ancak takas etmeniz gerekirse işler daha yavaş olacaktır. Ayrıca, bellek eşlemeleri (bkz. Numpy.memmap) diskteki büyük dosyalarla, belleğe yüklemeden çalışmanın bir yoludur, ancak yine de, bunun çok yararlı olması için 64 bitlik bir adres alanına sahip olmanız gerekir. PyTables bunun çoğunu sizin için de yapacak.



4

Bazen basit bir çözüm, matris öğeleriniz için özel bir tür kullanmaktır. İhtiyaç duyduğunuz sayı aralığına bağlı dtypeolarak, öğeleriniz için özel olarak daha küçük bir kılavuz kullanabilirsiniz . Numpy, varsayılan olarak nesne için en büyük türü dikkate aldığından, bu çoğu durumda yararlı bir fikir olabilir. İşte bir örnek:

In [70]: a = np.arange(5)

In [71]: a[0].dtype
Out[71]: dtype('int64')

In [72]: a.nbytes
Out[72]: 40

In [73]: a = np.arange(0, 2, 0.5)

In [74]: a[0].dtype
Out[74]: dtype('float64')

In [75]: a.nbytes
Out[75]: 32

Ve özel türle:

In [80]: a = np.arange(5, dtype=np.int8)

In [81]: a.nbytes
Out[81]: 5

In [76]: a = np.arange(0, 2, 0.5, dtype=np.float16)

In [78]: a.nbytes
Out[78]: 8

3

Terabayt RAM olmadan 2.500.000.000 element matrisinin nasıl işleneceğini mi soruyorsunuz?

8 milyar bayt RAM olmadan 2 milyar öğeyi işlemenin yolu, matrisi bellekte tutmamaktır.

Bu, onu dosya sisteminden parçalar halinde almak için çok daha karmaşık algoritmalar anlamına gelir.


7
Doğru değil. Elemanların% 99.99'u (gerçekçi bir örnek için) sıfırsa, matrisin tüm verileri bellekte tutulabilir. Var olan (row, column, value)girdilerin bir listesini saklayabildiğiniz zaman, her sıfır için 4 bayt kullanmanıza gerek yoktur.
Eric Wilson

6
@EricWilson: Sorunun neresinde matrisin seyrek olduğunu gösterdi? Bunu tamamen özledim. Teklif verebilir misiniz?
S.Lott


1

Uyuşuk hakkında bildiğim kadarıyla hayır, ama yanılıyor olabilirim.

Size şu alternatif çözümü önerebilirim: matrisi diske yazın ve ona parçalar halinde erişin. Size HDF5 dosya formatını öneririm. Şeffaf bir şekilde ihtiyacınız varsa, diskte depolanan matrisinizi belleğe sayfalandırmak için ndarray arayüzünü yeniden uygulayabilirsiniz. Verileri diskte yeniden eşitlemek için değiştirirseniz dikkatli olun.


57600 x 57600 matrisinin tamamına erişmek istersem ne olur?
Gunjan naik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.