Pracuję z dużymi matrycami danych (Nrow x Ncol), które są zbyt duże, aby można je było przechowywać w pamięci. Zamiast tego standardem w mojej dziedzinie pracy jest zapisywanie danych do pliku binarnego. Ze względu na charakter pracy, potrzebuję tylko dostępu do 1 kolumny macierzy na raz. Muszę też móc modyfikować kolumnę, a następnie zapisać zaktualizowaną kolumnę z powrotem do pliku binarnego. Do tej pory udało mi się dowiedzieć, jak zapisać macierz jako plik binarny i jak odczytać 1 "kolumnę" macierzy z pliku binarnego do pamięci. Jednak po edycji zawartości kolumny nie mogę wymyślić, jak zapisać tę kolumnę z powrotem do pliku binarnego.Julia: Jak zmodyfikować kolumnę matrycy, która została zapisana jako plik binarny?
Jako przykład załóżmy, że plik danych to 32-bitowa macierz tożsamości, która została zapisana na dysku.
Nrow = 500
Ncol = 325
data = eye(Float32,Nrow,Ncol)
stream_data = open("data","w")
write(stream_data,data[:])
close(stream_data)
Czytając cały plik z dysku, a następnie przekształcania z powrotem do macierzy jest prosta:
stream_data = open("data","r")
data_matrix = read(stream_data,Float32,Nrow*Ncol)
data_matrix = reshape(data_matrix,Nrow,Ncol)
close(stream_data)
Jak powiedziałem wcześniej, dane macierze Pracuję ze są zbyt duże, aby czytać w pamięci w rezultacie powyższy kod normalnie nie byłby możliwy do wykonania. Zamiast tego muszę pracować z 1 kolumną na raz. Poniżej przedstawiono rozwiązanie odczytu 1 w kolumnie (np 7. kolumn) macierzy do pamięci:
icol = 7
stream_data = open("data","r")
position_data = 4*Nrow*(icol-1)
seek(stream_data,position_data)
data_col = read(stream_data,Float32,Nrow)
close(stream_data)
Należy zauważyć, że współczynnik „4” w zmiennej „position_data”, ponieważ pracuję z Float32. Również nie w pełni zrozumieć, co robi komenda szukać tutaj, ale wydaje się, że daje mi poprawny wynik w oparciu o następujące testy:
data == data_matrix # true
data[:,7] == data_col # true
dla dobra tego problemu, powiedzmy, że mam Ustalono, że kolumna I załadowane (czyli 7 kolumny) musi zostać zastąpione zerami:
data_col = zeros(Float32,size(data_col))
problem teraz jest dowiedzieć się, jak zapisać tę kolumnę z powrotem do pliku binarnego bez wpływu na którykolwiek z pozostałych dane. Oczywiście zamierzam użyć "zapisu" do wykonania tego zadania. Jednak nie jestem do końca pewien, jak postępować. Wiem, że muszę zacząć od otwarcia strumienia danych; jednak nie jestem pewien, jakiego "trybu" muszę użyć: "w", "w +", "a" lub "a +"? Tutaj jest nieudana próba z użyciem „w”:
icol = 7
stream_data = open("data","w")
position_data = 4*Nrow*(icol-1)
seek(stream_data,position_data)
write(stream_data,data_col)
close(stream_data)
Oryginalny plik binarny (przed moja nieudana próba edytować plik binarny) zajęte 650000 bajtów na dysku. Jest to zgodne z tym, że macierz ma rozmiar 500x325, a liczby Float32 zajmują 4 bajty (to jest 4 * 500 * 325 = 650000). Jednak po mojej próbie edycji pliku binarnego zauważyłem, że plik binarny zajmuje teraz tylko 14000 bajtów przestrzeni. Jakaś szybka mentalna matematyka pokazuje, że 14000 bajtów odpowiada 7 kolumnom danych (4 * 500 * 7 = 14000). Szybkie sprawdzenie potwierdza, że plik binarny zastąpił wszystkie oryginalne dane nową macierzą o rozmiarze 500x7, której elementy są zerami.
stream_data = open("data","r")
data_new_matrix = read(stream_data,Float32,Nrow*7)
data_new_matrix = reshape(data_new_matrix,Nrow,7)
sum(abs(data_new_matrix)) # 0.0f0
Co muszę zrobić/zmienić, aby modyfikować tylko 7. "kolumnę" w pliku binarnym?
są [te] (http://docs.julialang.org/en/release-0.4/stdlib/io-network/#memory-mapped-i-o) tutaj? – daycaster
Może zmienić 'stream_data = open (" dane "," w ")' na 'stream_data = open (" dane "," w + ")' w aktualizacji wektora. Zwróć uwagę na 'w +'. Odpowiednia dokumentacja to http://docs.julialang.org/en/release-0.4/stdlib/io-network/#Base.open –
[SharedArrays] (http://docs.julialang.org/en/release-0.4 /stdlib/parallel/#Base.SharedArray) zrobi wszystko, co dla ciebie określiłeś. Użyj konstruktora o nazwie pliku –