RLE (Run-Length Encoding) - to metoda kodowania strumienia informacji, czyli traktujemy wszystkie dane, które trafiają do naszej funkcji jako jeden pojedynczy wektor danych. Jeżeli dostarczone do funkcji dane posiadają więcej niż 1 wymiar, to po uprzednim ich zapisaniu dane należy spłaszczyć .flatten()
.
Sam algorytm kompresji RLE opiera się na redukcji powtarzalności symboli (bitów, bajtów, symboli, pikseli itd.). Ciągi powtarzalnych symboli zastępujemy parą licznik_powtórzeń, symbol
. Jeżeli symbol się nie powtarza zastępuje się go parą 1 symbol
, czyli wystąpił on 1
raz. Przykładowo ciąg [1,1,1,1,1,2,2,2,3,4,5,6,6,6,6,1]
zostałby zakodowany jako [5,1,3,2,1,3,1,4,1,5,4,6,1,1]
.
Uprzedzając pytania: tak w skrajnie niesprzyjającym przypadku łańcuch skompresowany może być dwa razy dłuższy niż wejściowy. Żeby program działał szybciej, proponuję, żeby zamiast dodawać kolejne elementy do listy, założyć niekorzystny buffor i jego wypełniać. A na końcu przyciąć go tylko do finalnej długości.
*2) np.zeros(np.prod(data.shape)
Drobna sugestia — owszem pakiet numpy
ma funkcję pozwalającą znaleźć następny inny element, ale przeszukuje ona cały zakres danych, co znacząco wydłuża jej działanie, dlatego wygodniej w do tego wykorzystać zwykłą pętlę for
z break
. Jeżeli implementujecie również ByteRun, to warto zaimplementować to jako funkcję pomocniczą, bo tam również się przyda.