#python
#python
Вопрос:
Я пытаюсь написать код, который будет обрабатывать мой входной файл чисел, а затем выполнять различные операции над ними. Например, первый столбец — это имя. Второй — почасовая ставка, а третий — часы. Файл выглядит следующим образом,
John 15 8
Sam 10 4
Mike 16 10
John 19 15
Я хочу просмотреть, и если имя является дубликатом (John в примере), оно усреднит 2-е число (почасовая ставка), получит в сумме 3-е число (часы) и удалит дубликат, оставив 1 Джона со средней зарплатой и общим количеством часов. Если не дубликат, он просто выведет исходную запись.
Я не могу понять, как отслеживать дубликат, а затем переходить к следующей строке в строке. Есть ли какой-либо способ сделать это без использования line.split()?
Комментарии:
1. Почему вы не хотите использовать
split()
? Это звучит именно так, как вы хотите.2. Потому что split помещает значения в список, но мне нужно вывести числа такими, какими они были изначально (не разделенные запятыми).
3. После преобразования его в список с помощью split() вы всегда можете использовать » «.join(список), чтобы повторно преобразовать его в исходный формат? (Проверьте это: programiz.com/python-programming/methods/string/join )
Ответ №1:
Эта проблема решается проще, если разбить ее на части.
Сначала вы хотите прочитать файл и разобрать каждую строку на три переменные: имя, почасовую ставку и часы.
Во-вторых, вам нужно обработать сопоставление по первому значению (имени). Вам нужна какая-то структура данных для хранения значений; dict
вероятно, здесь то, что нужно.
В-третьих, вам нужно вычислить среднее значение в конце (вы не можете вычислить его по ходу дела, потому что вам нужно количество значений).
Собрав все вместе, я бы сделал что-то вроде этого:
class PersonRecord:
def __init__(self, name):
self.name = name
self.hourly_rates = []
self.total_hours = 0
def add_record(self, hourly_rate, hours):
self.hourly_rates.append(hourly_rate)
self.total_hours = hours
def get_average_hourly_rate(self):
return sum(self.hourly_rates) / len(self.hourly_rates)
def compute_person_records(data_file_path):
person_records = {}
with open(data_file_path, 'r') as data_file:
for line in data_file:
parts = line.split(' ')
name = parts[0]
hourly_rate = int(parts[1])
hours = int(parts[2])
person_record = person_records.get(name)
if person_record is None:
person_record = PersonRecord(name)
person_records[name] = person_record
person_record.add_record(hourly_rate, hours)
return person_records
def main():
person_records = compute_person_records()
for person_name, person_record in person_records.items():
print('{name} {average_hourly_rate} {total_hours}'.format(
name=person_name,
average_hourly_rate=person_record.get_average_hourly_rate(),
total_hours=person_record.total_hours))
if __name__ == '__main__':
main()
Ответ №2:
Поехали. Просто groupby
name
и aggregate
над rate
и hours
берем mean
и sum
, как показано ниже.
#assume d is the name of your DataFrame.
d.groupby(by =['name']).agg({'rate': "mean", 'hours':'sum'})
Ответ №3:
Вот версия, которая не особенно эффективна. Я бы не стал запускать его с большим количеством данных, но он легко читается и возвращает ваши данные в исходную форму, что, по-видимому, и является тем, что вы хотите…
from statistics import mean
input = '''John 15 8
Sam 10 4
Mike 16 10
John 19 15'''
lines = input.splitlines()
data = [line.split(' ') for line in lines]
names = set([item[0] for item in data])
processed = [(name, str(mean([int(i[1]) for i in data if i[0] == name])), str(sum([int(i[2]) for i in data if i[0] == name]))) for name in names]
joined = [' '.join(p) for p in processed]
line_joined = 'n'.join(joined)
Ответ №4:
a=[] #list to store all the values
while(True): #infinite while loop to take any number of values given
try: #for giving any number of inputs u want
l=input().split()
a.append(l)
except(EOFError):
break;
for i in a:
m=[i] #temperory list which will contain duplicate values
for j in range(a.index(i) 1,len(a)):
if(i[0]==a[j][0]):
m.append(a[j]) #appending duplicates
a.pop(j) #popping duplicates from main list
hr=0 #initializing hourly rate and hours with 0
hrs=0
if(len(m)>1):
for k in m:
hr =int(k[1])
hrs =int(k[2])# calculating total hourly rate and hours
i[1]=hr/len(m)
i[2]=hrs/len(m)#finding average
for i in a:
print(i[0],i[1],i[2]) # printing the final list
Прочитайте комментарии в коде для пояснения кода
Ответ №5:
Вы можете сделать:
from collections import defaultdict
with open('file_name') as fd:
data = fd.read().splitlines()
line_elems = []
for line in data:
line_elems.append(line.split())
a_dict = defaultdict(list)
for e in line_elems:
a_dict[e[0]].append((e[1], e[2]))
final_dict = {}
for key in a_dict:
if len(a_dict[key]) > 1:
hour_rates = [float(x[0]) for x in a_dict[key]]
hours = [float(x[1]) for x in a_dict[key]]
ave_rate = sum(hour_rates) / len(hour_rates)
total_hours = sum(hours)
final_dict[key] = (ave_rate, total_hours)
else:
final_dict[key] = a_dict[key]
print(final_dict)
# write to file or do whatever