Проблема чтения файла Python, возможен ли инфильный цикл? - PullRequest
0 голосов
/ 24 октября 2018

Вопрос в следующем;«Напишите программу на Python для чтения файла с данными об озере и рыбе и установите отчет в виде идентификационного номера озера, названия озера и веса рыбы в табличном формате (используйте строковые зоны с форматированием). Программа должна рассчитать средний вес рыбысообщается. "

Идентификация озера;

1000 Chemo
1100 Greene
1200 Toddy

Файл, который я должен прочитать" FishWeights.txt ", содержит следующие данные;

1000 4.0
1100 2.0
1200 1.5
1000 2.0
1000 2.2
1100 1.9
1200 2.8

Мой код;

f = open("fishweights.txt")
print(f.read(4), "Chemo", f.readline(4))
print(f.read(5), "Greene", f.read(5))
print(f.read(4), "Toddy", f.read(5))
print(f.read(5), "Chemo", f.read(4))
print(f.read(5), "Chemo", f.read(4))
print(f.read(5), "Greene", f.read(4))
print(f.read(5), "Toddy", f.read(4))

Вывод, который я получаю, является:

1000 Chemo  4.0

1100 Greene  2.0

1200 Toddy  1.5

1000  Chemo 2.0

1000  Chemo 2.2

1100  Greene 1.9

1200  Toddy 2.8 

Это верно в той степени, в которой мне необходимо отобразить идентификационный номер озера, имя и вес рыбы на озеро.Но мне нужно иметь возможность рассчитать, где в конце он усредняет все веса рыб.Вывод ДОЛЖЕН быть аккуратно отформатирован и выглядеть следующим образом:

1000     Chemo      4.0
1100     Greene     2.0
1200     Toddy      1.5
1000     Chemo      2.0
1000     Chemo      2.2
1100     Greene     1.9
1200     Toddy      2.8
The average fish weight is: 2.34

Любая помощь приветствуется. Просто начинающий программист, ищущий помощи, чтобы получить полное понимание предмета.Спасибо!

Ответы [ 5 ]

0 голосов
/ 24 октября 2018

Это может быть легко достигнуто с помощью dataframe.Пожалуйста, найдите образец кода ниже.

import pandas as pd

# load lake data into a dataframe
lakeDF = pd.read_csv('Lake.txt', sep=" ", header=None)
lakeDF.columns = ["Lake ID", "Lake Name"]
#load fish data into a dataframe
fishWeightDF = pd.read_csv('FishWeights.txt', sep=" ", header=None)
fishWeightDF.columns = ["Lake ID", "Fish Weight"]
#sort fishweight with 'Lake ID' (common field in both lake and fish)
fishWeightDF = fishWeightDF.sort_values(by= ['Lake ID'],ascending=True)
# join fish with lake
mergedFrame = pd.merge_asof(
    fishWeightDF, lakeDF,
    on='Lake ID'
    )
#print the result
print(mergedFrame)
#find the average
average = mergedFrame['Fish Weight'].mean()
print(average)
0 голосов
/ 24 октября 2018

Таким образом, здесь вы можете хранить вес вашей рыбы и данные о озере в двух массивах.Смотрите ниже, где он читает каждую строку, а затем разбивает их на список весов рыб и список данных по озеру.

text=f.readlines()
fishWeights=[] 
lakeData=[]
for item in text:
    fishWeights.append(item.split(' ')[1])
    lakeData.append(item.split(' ')[1])

Отсюда вы можете выводить информацию с помощью

for i in range(len(fishWeights)) :
    print(lakeData[i], "Your Text", fishWeights[i])

И вы можете рассчитать среднее значение с помощью

total=0
for weight in fishWeights:
    total+=weight
total/=len(fishWeights) 
0 голосов
/ 24 октября 2018

Вам не нужно использовать смещения для чтения строк.Кроме того, вы можете использовать with, чтобы убедиться, что файл закрыт, когда вы закончите.Для среднего вы можете поместить все числа в список и найти среднее в конце.Используйте словарь для сопоставления идентификаторов озер с именами:

lakes = {
    1000: "Chemo",
    1100: "Greene",
    1200: "Toddy"
}
allWeights = []

with open("test.txt", "r") as f:
    for line in f:
        line = line.strip()  # get rid of any whitespace at the end of the line
        line = line.split()

        lake, weight = line
        lake = int(lake)
        weight = float(weight)
        print(lake, lakes[lake], weight, sep="\t")
        allWeights.append(weight)

avg = sum(allWeights) / len(allWeights)
print("The average fish weight is: {0:.2f}".format(avg)) # format to 2 decimal places

Вывод:

1000    Chemo   4.0
1100    Greene  2.0
1200    Toddy   1.5
1000    Chemo   2.0
1000    Chemo   2.2
1100    Greene  1.9
1200    Toddy   2.8
The average fish weight is: 2.34

Есть более эффективные способы сделать это, но это, вероятно, самый простой способ помочь вам понять, чтопродолжается.

0 голосов
/ 24 октября 2018

Вы можете сохранить названия своих озер в словаре, а свои данные - в списке.Оттуда вам просто нужно пройтись по списку fish в этом примере и получить названия озер, соответствующие id.Наконец, напечатайте среднее значение ниже, просто сложив weight из списка и разделив его на длину fish.

with open('LakeID.txt','r') as l:
    lake = l.readlines()
    lake = dict([i.rstrip('\n').split() for i in lake])

with open('FishWeights.txt','r') as f:
    fish = f.readlines()
    fish = [i.rstrip('\n').split() for i in fish]

for i in fish:
    print(i[0],lake[i[0]],i[1])    

print('The total average is {}'.format(sum(float(i[1]) for i in fish)/len(fish))) 

. Также рекомендуется использовать диспетчер контекста with open(..), который делаетуверен, что файл закрывается при выходе.

0 голосов
/ 24 октября 2018

Да, вам нужно перебрать строки.Это конструкция, которую вы ищете:

with open("fishweights.txt") as fo:
    for line in fo:
        pass

Теперь для извлечения каждого фрагмента каждой строки вы можете использовать line.split().Чтение фиксированного числа байтов (как вы это сделали) хорошо, если предположить, что идентификаторы имеют фиксированную длину.Вы уверены, что каждый идентификатор всегда будет иметь ровно 4 цифры?Что-то вроде этого может быть лучше:

raw_data = []
with open("fishweights.txt") as fo:
    for line in fo:
        row = line.strip().split()
        if not row:
            continue  # ignore empty lines
        id = int(row[0])
        no = float(row[1])
        raw_data.append((id, no))

Теперь, когда у вас есть необработанные данные, вам нужно их агрегировать:

sum = 0
count = 0
for id, no in raw_data:
    sum += no
    count += 1
avg = sum / count

или однострочный

avg = sum(no for id, no in raw_data) / len(raw_data)

и, наконец, вам необходимо сопоставить идентификаторы с именами для окончательной печати:

id_to_name = {
    1000: 'Chemo',
    1100: 'Greene',
    1200: 'Toddy',
}
for id, no in raw_data:
    print(id, id_to_name[id], no)
print('Average: ', avg)

Конечно, все три цикла можно объединить в один цикл.Я разделил его так, чтобы вы могли четко видеть каждый этап кода.Окончательный (и немного оптимизированный) результат может выглядеть так:

id_to_name = {
    1000: 'Chemo',
    1100: 'Greene',
    1200: 'Toddy',
}
sum = 0
count = 0
with open("fishweights.txt") as fo:
    for line in fo:
        row = line.strip().split()
        if not row:
            continue  # ignore empty lines
        id = int(row[0])
        no = float(row[1])
        sum += no
        count += 1
        print(id, id_to_name[id], no)
print('Average:', sum/count)
...