Mam następujący plik csv, który zawiera te wiersze:

;name;;;surname;;age;salary;
0;john;;;snow;;38;1000;
1;nick;;;kalathes;;22;500;
0;roger;;;smith;;21;400;
1;mona;;;liza;;18;1000;
1;bill;;;alios;;48;2000;

Czytam plik csv za pomocą csv.reader:

import csv,sys
filename='test1.csv'
with open(filename, mode='r', newline='', encoding='utf-8') as f:
    reader=csv.reader(f)
    try:
        for row in reader:
            print(row)

Wynik:

[';name;;;surname;;age;salary;']
['0;john;;;snow;;38;1000;']
['1;nick;;;kalathes;;22;500;']
['0;roger;;;smith;;21;400;']
['1;mona;;;liza;;18;1000;']
['1;bill;;;alios;;48;2000;']

Moim celem jest znalezienie maksymalnego wieku, jeśli wiersz zaczyna się od "1". Przypuszczam, że w pierwszym kroku muszę znaleźć pozycję ciągu 'age' w pierwszym wierszu. (w tym przykładzie wiek jest siódmym elementem (oddzielonym ;).

Pracuję nad tym, próbując czegoś takiego:

for row in reader:
    print(row)
    print(type(row))
    indexes = [i for i,x in enumerate(row) if x == "age"]
    print(indexes)

Ale jak dotąd nie odniósł sukcesu. Myślę, że kiedy będę mógł poznać pozycję tego, będę musiał sprawdzić, czy jakieś wiersze zaczynają się od "1". potem muszę znaleźć max i min z tych wierszy. Potrafię to zrobić w java, javscript, c itp., ale jestem początkującym w pytonie. Pseudokod, który muszę zaimplementować, może wyglądać tak:

for(i=0; i<list.length; i++ {
    if (list.includes("age") {
        position=stringAt(age)
        break;
    }
for(i=0; i<list.length; i++ {
   if (list[0]==1) {
       tmp.push(list[position]
}
print(max.tmp)
0
Nakos Kotsanis 17 grudzień 2019, 02:21
Czy chcesz poznać indeks wiersza z minimalnym i maksymalnym wiekiem, czy tylko jakie są te dwie wartości?
 – 
martineau
11 marzec 2020, 13:39

5 odpowiedzi

Określ średnik jako separator, wtedy jest to dość proste:

reader = csv.reader(f, delimiter=';')
ages = [row[6] for row in reader if row[0] == '1']
max_age = sorted(ages)[-1]
2
Colin 17 grudzień 2019, 02:35

Zawsze należy czytać dokumenty (Czytanie i zapisywanie plików CSV).

Twój plik CSV nie jest „standardowym” plikiem CSV, więc musisz określić separator („;”)

reader=csv.reader(f, delimiter=';')

Teraz wynik będzie następujący:

['0', 'jan', '', '', 'śnieg', '', '38', '1000', '']

[„1”, „nick”, „”, „”, „kalathes”, „”, „22”, „500”, „”]

1
exiz 17 grudzień 2019, 02:30

Użyłbym DictReader oraz wbudowanych funkcji min i max:

import csv,sys
filename='test1.csv'
with open(filename, mode='r', newline='', encoding='utf-8') as f:
    reader=csv.DictReader(f, delimiter=";")
    print(min(int(row['age']) for row in reader))
with open(filename, mode='r', newline='', encoding='utf-8') as f:
    reader=csv.DictReader(f, delimiter=";")
    print(max(int(row['age']) for row in reader))

Może być konieczne użycie try i except, jeśli dane nie są gwarantowane.

2
Mark Bailey 11 marzec 2020, 17:23

Ponieważ Twój plik CSV jest rozdzielony średnikami, musisz to określić podczas tworzenia csv.reader. Reszta przetwarzania jest stosunkowo prosta:

import csv, sys

DELIMITER = ';'
FILENAME = 'minmax_test.csv'

with open(FILENAME, mode='r', newline='', encoding='utf-8') as f:
    reader = csv.reader(f, delimiter=DELIMITER)

    # Find index of "age" field.
    header = next(reader)
    for i, field in enumerate(header):
        if field == 'age':
            age_index = i
            break
    else:
        raise RuntimeError('No field named "age" found in csv file')

    # Find min and max ages of rows that start with "1".
    min_age, max_age = sys.maxsize, -sys.maxsize-1
    min_age_row, max_age_row = None, None
    min_age_name, max_age_name = '', ''

    for i, row in enumerate(reader):
        print('row[{}]: {}'.format(i, row))
        if row[0] == '1':
            age = int(row[age_index])
            if age < min_age:
                min_age = age
                min_age_row = i
                min_age_name = row[1]
            if age > max_age:
                max_age = age
                max_age_row = i
                max_age_name = row[1]

    print('min - name: {!r}, age: {} in row {}'.format(min_age_name, min_age, min_age_row))
    print('max - name: {!r}, age: {} in row {}'.format(max_age_name, max_age, max_age_row))

Wynik:

row[0]: ['0', 'john', '', '', 'snow', '', '38', '1000', '']
row[1]: ['1', 'nick', '', '', 'kalathes', '', '22', '500', '']
row[2]: ['0', 'roger', '', '', 'smith', '', '21', '400', '']
row[3]: ['1', 'mona', '', '', 'liza', '', '18', '1000', '']
row[4]: ['1', 'bill', '', '', 'alios', '', '48', '2000', '']
min - name: 'mona', age: 18 in row 3
max - name: 'bill', age: 48 in row 4
2
martineau 17 grudzień 2019, 05:23

Czy istnieje sposób, aby uzyskać wyniki w porządku malejącym? teraz mogę wydrukować maksymalną i minimalną linię pliku

min - name: 'mona', age: 18 
max - name: 'bill', age: 48 

Szukam sposobu na wydrukowanie wszystkich wierszy, które zaczynają się od „1” (z porządkiem), na przykład:

bill - 48
nick - 22
mona - 18
...

Czy muszę używać stale różnych pętli dla każdego wyniku, który chcę?

0
Nakos Kotsanis 17 grudzień 2019, 17:48