Выполнение различных операций над столбцами в файле

#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