W poprzednim ćwiczeniu napisałem kod, który wypisuje wysokość każdej góry pliku csv. Możesz go znaleźć tutaj:

import csv

def mountain_height(filename):
    """ Read in a csv file of mountain names and heights.  
    Parse the lines and print the names and heights. 
    Return the data as a dictionary. 
    The key is the mountain and the height is the value.
    """

    mountains = dict()
    msg = "The height of {} is {} meters."
    err_msg = "Error: File doesn't exist or is unreadable."

    # TYPE YOUR CODE HERE.
    try:
        with open('mountains.csv', 'r') as handle:
            reader = csv.reader(handle, delimiter=',')

            for row in reader:
                name = row[0]
                height = row[1]
                mountains[name] = int(height)

            for name, height in mountains.items():
                print("The height of {names} is {heights} meters.".format(names=name, heights=height))

    except:
        print("Error: Something wrong with your file location?")
        return None

Nie jestem pewien, czy jest idealny, ale wydaje się, że działa.

Oto podgląd pliku csv: mountains.csv

Teraz muszę przepisać ten kod za pomocą modułu kolekcji Licznik, aby policzyć, ile razy wspomniano o każdym pasmie górskim. Każdy rząd zawiera górę, jej wysokość i zakres, którego jest częścią.

Muszę również dodać słownik, który rejestruje wszystkie wysokości gór w określonym paśmie. Muszę użyć listy dla wartości wysokości. Klucz będzie nazwą zakresu. Za każdym razem, gdy pojawia się nowa góra w paśmie, wysokość musi zostać dodana do listy dla tego klucza. Na przykład, po odczytaniu wszystkich danych, góry ['Himalaje'] == [8848, 8586, 8516, 8485, 8201, 8167, 8163, 8126, 8091, 8027]. (Zakresem są „Himalaje”).

Wyjście powinno polegać na wydrukowaniu 2 górnych zakresów i dodaniu nazwy zakresu do licznika. Następnie wydrukuj średnią wysokość gór w każdym zakresie. Po wydrukowaniu zwróć obiekt słownikowy z zakresami i ich listami wysokości gór.

Mam bardzo małe wyobrażenia o module Licznik i czuję się przytłoczony tym zadaniem. Czy masz jakieś rady, od czego zacząć?

Oto, co mam do tej pory:

from collections import Counter
from collections import defaultdict
from statistics import mean
def mountain_ranges(filename):
    ranges = Counter()
    heights = defaultdict(list)

Z góry dziękuję....

0
Charlotte Grosjean 19 grudzień 2019, 17:06
1
Czy możesz pokazać przykładowy plik CSV i oczekiwane dane?
 – 
Alderven
19 grudzień 2019, 17:16
2
Dlaczego „musisz” używać Counter?
 – 
PyPingu
19 grudzień 2019, 17:22
Myślę, że to raczej kwestia strategii rozwiązywania problemów w ogóle? Zastanów się, jak byś to zrobił „ręcznie”, zidentyfikuj grupowalne kroki w przepływie pracy (podzadania) i sprawdź, czy jakaś predefiniowana biblioteka może pomóc ci w niektórych krokach (takich jak Licznik tutaj). dziel i rządź...
 – 
jerch
19 grudzień 2019, 17:25
W poście dodałem link do podglądu pliku CSV, mam nadzieję, że to pomoże!
 – 
Charlotte Grosjean
19 grudzień 2019, 17:31
Muszę go użyć, ponieważ jest to wymagane do ćwiczenia ekstrakcji danych w ramach kursu internetowego, który śledzę. Jednak nigdy wcześniej go nie używałem i nadal jestem na początku kursu i trochę zagubiony...
 – 
Charlotte Grosjean
19 grudzień 2019, 17:34

1 odpowiedź

Poniższe wydrukuje to, o co prosiłeś, i zwróci licznik i słownik wysokości.

import csv
from collections import defaultdict, Counter
from statistics import mean


def mountain_height(filename):
    """ Read in a csv file of mountain names and heights.  
    Parse the lines and print the names and heights. 
    Return the data as a dictionary. 
    The key is the mountain and the height is the value.
    """
    range_heights = defaultdict(list)
    range_count = Counter()
    # TYPE YOUR CODE HERE.
    try:
        with open(filename, 'r') as handle:
            reader = csv.reader(handle, delimiter=',')
            for row in reader:
                if row:
                    name = row[0]
                    height = row[1]
                    mrange = row[2]
                    range_heights[mrange].append(int(height))
                    range_count[mrange] += 1
    except:
        print("Error: Something wrong with your file location?")
        return None

    print("The 2 most frequent ranges are:")
    for mrange in range_count.most_common(2):
        print(f"{mrange[0]} has {mrange[1]} mountains")
    print("The average heights of each range are:")
    for mrange, heights in range_heights.items():
        print(f"{mrange} -- {mean(heights)}m")

    return range_count, range_heights


counts, heights = mountain_height('mountains.csv')


The 2 most frequent ranges are:
Himalayas has 10 mountains
Karakoram has 4 mountains
The average heights of each range are:
Himalayas -- 8321m
Karakoram -- 8194.25m

Więc wiesz, osobiście nie wierzę, że używanie Counter tutaj jest konieczne lub „właściwy” sposób robienia rzeczy, ale ponieważ tego potrzebujesz, to właśnie ci dałem. W rzeczywistości nie jest to nawet jedyny sposób, w jaki możesz użyć Counter tutaj - możesz utworzyć listę każdego zakresu podczas przeglądania wierszy, a następnie po prostu zastosować Counter(list_of_ranges), ale dla większych plików oznaczałoby to tworzenie dużej listy w pamięci, która znowu wydaje się bezcelowa.

Dla jasności moim osobistym rozwiązaniem na obliczanie wyników bez Counter byłoby po prostu użycie słownika range_heights i dyktowanie ze zrozumieniem w następujący sposób:

range_counts = {r: len(heights) for r, heights in range_heights.items()}

0
PyPingu 19 grudzień 2019, 17:57
Imho publikowanie rozwiązania c&p nie jest tutaj zbyt pomocne, również twoje przemyślenia na temat zużycia pamięci/optymalizacji chybiają celu – wydaje się, że OP powinien nauczyć się wykorzystywać gotowe do użycia elementy i elementy.
 – 
jerch
19 grudzień 2019, 18:06
Mogłem po prostu połączyć się z dokumentacją na Counter, ale czułem się miłosierny, więc po prostu wstawiłem przykład z dokumentacji do kodu OPs.
 – 
PyPingu
19 grudzień 2019, 18:11
Odpowiedź PyPingu była pomocna w tym sensie, że teraz rozumiem, że użycie „Counter” nie jest tutaj najbardziej wydajne. Teraz muszę wydrukować wysokość każdej góry w postaci listy, a teraz mogę spróbować zrobić to samodzielnie, ponieważ mam bazę! Dzięki PyPingu ;)
 – 
Charlotte Grosjean
19 grudzień 2019, 18:23