2013-06-11 34 views
6

Muszę więc nagrać zestaw 4 liczb całkowitych, których wartości są różne dla każdej sekundzie dnia. tj .:Edycja pojedynczej linii w dużym pliku tekstowym

#Here the values are initialized to the same value, however they will change as samples are taken 
data = [[.25 for numData in range(4)] for numSecs in range(86400)] 

Teraz oczywiście dwuwymiarowa macierz (GAH jego Python, listy), którego pierwszy indeks długość wynosi 86400 jest dość niepraktyczne. Zamiast tego chcę utworzyć plik tekstowy z 86400 wierszy sformatowane jako takie:

numSec data0 data1 data2 data3 

0 .25 .25 .25 .25 
1 .25 .25 .25 .25 
2 .25 .25 .25 .25 
... 

I jak pobierane są próbki, chcę móc edytować ten plik, ba, chcę móc edytować linię plik, którego numSec = drugi po pobraniu próbki. Na przykład, próbka pobrana w numSec = 2 (2 sekundy po północy) mogłyby spowodować mój program do edycji pliku, tak aby:

0 .25 .25 .25 .25 
1 .25 .25 .25 .25 
2 .70 .10 .10 .10 
... 

wydaje się dość proste, muszę jeszcze przeczytać kilka postów, które pokazały, jak na przepisać singiel w pliku tekstowym. Problem polega na tym, że wszystkie one wymagają przeczytania w całym pliku. Nie chcę, aby mój program czytał 86 400 linii na sekundę.

W ten sposób dochodzimy do mojego pytania: Czy mogę odczytać pojedynczą linię w pliku tekstowym, edytować i zapisać ją w pliku, bez czytania całego pliku za każdym razem, gdy trzeba wprowadzić zmianę?

P.S. Powinienem zauważyć, że korzystam z Ubuntu 12.04 (Precise) i to jest do użytku w węźle ROS

PPS Ten program będzie działać przez dowolną liczbę dni, aby każdy "drugi" danych mógł być wielokrotnie czytany i przepisywany . Innym powodem, dla którego chciałbym użyć pliku, jest to, że system musi zostać wyłączony, chciałbym zapisać dystrybucje przy następnym uruchomieniu.

+7

Jeśli każdy wpis w pliku ma ustaloną długość, być może 'mmap'. Inaczej, rozważ bazę danych. – Jokester

+0

Jeśli każdy wpis ma stałą długość, możesz _powidzieć plik w trybie binarnym, obliczyć przesunięcie, 'seek' i' write' na miejscu.(To będzie działać również w trybie tekstowym, o ile uwzględnisz nowe linie i szerokości znaków, ale jest to technicznie nielegalne.) Jednak 'mmap' prawdopodobnie będzie prostsze, więc daj +1 jokesterowi. – abarnert

+1

Co sprawia, że ​​przechowywanie 86400 zestawów po 5 liczb jest problemem? W każdym razie musisz pisać średnio połowę pliku co sekundę. Ponadto, każda sekunda będzie zajmować się linią bezpośrednio po poprzedniej linii - dlaczego nie zachować wszystkiego w pamięci? – Neil

Odpowiedz

3

Może być konieczne zmodyfikowanie tego fragmentu i założenie, że wszystkie linie mają tę samą długość. W tym celu musiałem ustawić pierwszą kolumnę na stałą szerokość. Ale jeśli nie chcesz dopełnienia, powinieneś być w stanie obliczyć liczbę liczb 1,2,3,4, .. cyfr przed danym rzędem.

data = [[.25 for numData in range(4)] for numSecs in range(86400)] 
length_line=0 

def write_line(f, sec, data): 
    line="{:6d}".format(sec) + " " +" ".join(
      ["{:.2f}".format(dd) for dd in data])+"\n" 
    f.write(line) 
    return len(line) 

with open('output', 'w') as of: 
    for i,d in enumerate(data): 
     length_line=write_line(of, i, d) 

with open('output', 'rb+') as of: 
    # modify the 2nd line: 
    n = 2 
    of.seek(n*length_line) 
    write_line(of, n, [0.10,0.10,0.10,0.10]) 
    # modify the 10th line: 
    n = 10 
    of.seek(n*length_line) 
    write_line(of, n, [0.10,0.10,0.10,0.10]) 
+0

Dzięki za odpowiedź, Podczas gdy mam problemy z odszyfrowaniem write_line (nie martw się, wymyślę to) Widzę, że wciąż deklarujesz dwuwymiarową tablicę. Problemem odczytu/zapisu jest uniknięcie tej struktury, a tym samym niepotrzebne korzystanie z odczytu/zapisu. Domyślam się, że mam nowe pytanie, czy 86400 zestawów 5 liczb naprawdę nie jest tak wielkim kosmicznym wieprzem? – RoboCop87

+0

@ RoboCop87, zadeklarowałem to tylko zapełnić plik wyjściowy do testowania. W ogóle nie potrzebujesz tablicy 2d. Ale musisz napisać początkowy plik. Ta struktura powinna jednak zużywać mniej niż 10 MB. – perreal

+0

Nie jestem pewien, czy znasz ROS (zdecydowanie nie, i mam go używać), ale z tego co rozumiem, działa wiele programów w tym samym czasie i bardzo obciąża twój system . Nie jestem pewien, ile 10MB ma wpływ na taki system, dlatego starałem się zachować ostrożność przy korzystaniu z tego pliku. Czy to ledwie sterowiec w zakresie informatyki? Czy może to coś zmienić? – RoboCop87

2

Jeśli linie mają różną długość, to wszystko po zmodyfikowanej linii będzie znajdować się w niewłaściwej pozycji i musisz przepisać wszystkie te wiersze. Jeśli wszystkie linie mają tę samą długość, można uzyskać nowe dane, obliczając przesunięcie linii w pliku. Aby uzyskać więcej informacji, patrz Python File Objects.

0

Nie jestem pewien, czy jest przydatny do przechowywania 345600 (86400 * 4) razy 0,25. Po prostu zapisz wartość domyślną w pierwszym wierszu. Następnie dodaj jedną linię naraz. Jeśli znaczniki czasu nie pojawiają się w kolejności, po prostu umieść je tak, jak są, a po zakończeniu dnia posortuj zawartość pliku i wypełnij brakujące znaczniki czasu wartością domyślną. Przykład:

default: 0.25 
2 .70 .10 .10 .10 
3 .80 .20 .20 .20 
1 .50 .30 .30 .30 
5 .40 .30 .30 .30 

Później proces ten plik, aby uzyskać w ten sposób:

1 .50 .30 .30 .30 
2 .70 .10 .10 .10 
3 .80 .20 .20 .20 
4 .25 .25 .25 .25 
5 .40 .30 .30 .30 
+0

Widzę, co mówisz, jednak ten program będzie działał przez dowolną liczbę dni, więc samo dołączanie pojedynczego elementu nie byłoby skutecznym rozwiązaniem. – RoboCop87

0

If I were you, chciałbym użyć sqlite bazy danych do przechowywania zapisów. Klucz byłby drugą obserwacją, a każdy wiersz składałby się z 4 wartości. Aktualizacja i edycja byłyby znacznie bardziej wydajne.

Powiązane problemy