Przypisanie klasy do wartości

0

Należy napisać funkcję, która zwróci 1 lub 0. Lista to pomiary. Jedynka ma być zwracana wtedy, kiedy pomiar był wykonany na większej głębokości niż poprzedni.
Przykładowe dane:
depth = [0.7, 0.5, 0.8, 1, 1.3, 1.8, 1.5, 1.6, 2.1 ]
Jak zrobić to, aby funkcja zwracała jedynkę kiedy element listy jest większy od poprzedniego, a jeśli mniejszy to 0? Np. 0.8 > 0.5, więc dla 0.8 chce zwrócić 1 itd.

0
[1 if i>j else 0 for i,j in zip(depth, depth[1:])]  # [1, 0, 0, 0, 0, 1, 0, 0]

Pytanie, co z ostatnim elementem? Powyższy kod go nie uwzględnia, bo ostatni element nie ma następnika.

0

Nie do końca o to mi chodziło. Dla ostatniego elementu powinno zwrócone być 1, ponieważ 2.1 > 1.6. Wartość 0 zwrócona powinna być tylko dla 0.5 i 1.5

0

No to wystarczy odwrócić znak nierówności w warunku:

[1 if i<j else 0 for i,j in zip(depth, depth[1:])]  # [0, 1, 1, 1, 1, 0, 1, 1]

Tym razem powstaje pytanie co z pierwszym elementem, dla którego nie istnieje poprzednik? Zwracana lista jest o jeden element mniejsza niż depth.

0

@Pyxis: Tak, tylko na odwrót:

[1 if i>j else 0 for j,i in zip(depth, depth[1:])]

EDYCJA: W ytm samym czasie, co to pisałem, sie Poprawiłeś. Pierwszy element, mógłby mieć z definicji jeden - skoro nie było przed nim pomiaru. Trzeba jeszcze pamiętać, że wejście musi mieć długość > 1.

0

Można i bez zipa:

>>> [int(depth[n] < depth[n+1]) for n in range(0, len(depth)-1)]
[0, 1, 1, 1, 1, 0, 1, 1]

0

Przepraszam za złe wyjaśnienie problemu. Co w takim razie z pierwszą wartością czyli 0.7 dla której chciałabym zwrócić 1?

0
def cmp(a, b):
    return int(a < b)

print(list(map(cmp, depth, depth[1:])))
0

Skoro wiemy, że zawsze ma być 1 na pierwszym miejscu to najprościej:

result = [1] + [1 if i<j else 0 for i,j in zip(depth, depth[1:])]
0
stokrotka9 napisał(a):

Przepraszam za złe wyjaśnienie problemu. Co w takim razie z pierwszą wartością czyli 0.7 dla której chciałabym zwrócić 1?

Chcę stworzyć funkcję, która dla wszystkich danych w innym programie przypisze mi właśnie wartości 0 lub 1.
Są to dane pomiarów głębokości. Jeżeli głębokość jest większa (czyli wartosci rosna) to potrzebuje przypisac 1, jesli nagle pojawia się wartość mniejsza jak np. w sekwencji (0.7, 0.5, 0.8, czyli tutaj 0.5 = 0) to znak że sonda podniosła się do góry w wyniku tego że nadeszła fala. Funkcję muszę użyć w programie ArcGis Pro, w narzędziu calculate field, która pomoże mi wyrzucić wszystkie rekordy z przypisanymi zerami.

0

A tak swoją drogą jakby tylko użyć pairwise zamiast slice to byłby fajny przykład algorytmu dla którego typ sekwencji nie ma znaczenia.

https://docs.python.org/3/library/itertools.html

0
stokrotka9 napisał(a):

Chcę stworzyć funkcję, która dla wszystkich danych w innym programie przypisze mi właśnie wartości 0 lub 1.

Najprościej przypisać takie wartości za pomocą słownika:

{**{depth[0]:1}, **{j:1 if i<j else 0 for i,j in zip(depth, depth[1:])}}

# {0.7: 1, 0.5: 0, 0.8: 1, 1: 1, 1.3: 1, 1.8: 1, 1.5: 0, 1.6: 1, 2.1: 1}

Jest jednak tutaj haczyk. Jeśli w liście pojawią się te same elementy, to wyjściowy słownik będzie zawierał dla powtarzającej się wartości tylko jedną parę wartość: 0/1. I nawet jakbyś próbowała zrobić to bez słownika, to musisz uwzględniać zawsze pozycję takiego elementu. Przykładowo kluczami mogą być tuple złożone z pary (wartość, pozycja), czyli zamiast wartość: 0/1 byłoby (wartość, pozycja): 0/1:

{**{(depth[0],0):1}, **{(e[1],p+1):1 if e[0]<e[1] else 0 for p,e in enumerate(zip(depth, depth[1:]))}}

# {(0.7, 0): 1,
# (0.5, 1): 0,
# (0.8, 2): 1,
# (1, 3): 1,
# (1.3, 4): 1,
# (1.8, 5): 1,
# (1.5, 6): 0,
# (1.6, 7): 1,
# (2.1, 8): 1}
0

Dlatego najpierw pisze się testy. Wtedy w tym wątku byłyby tylko trzy odpowiedzi: 1. klasyczny Pyxis 2. rozwiązanie z jednym przejściem oraz O(1) extra space 3. podziękowania.

1 użytkowników online, w tym zalogowanych: 0, gości: 1