2015-09-10 4 views
5

Я новичок в Python и не могу справиться с одним из моментов моего проекта, поэтому я был бы рад, чтобы ты помог мне :)Python - Вычисление второго столбца первого в файле

Давайте-х представьте себе, у меня есть * .txt файл с только один столбец, который выглядит как:

  Column-1 

row-1 0 
row-2 25.00 
row-3 27.14 
row-4 29.29 
row-5 31.43 
row-6 33.57 

* Колонка со строками добавляется сюда, чтобы упростить объяснение.

Мне нужно вычислить второй столбец, который принимает в качестве входных данных из столбца-1 и выводит результат вычитания этого значения строки из предыдущего (если значение строки-1 (столбец-1) равно 0, чем это должно быть 0 в строке-1 (колонка-2)). Это должно быть, как:

  • строка-2 (колонок-2) = строка-2 (колонок-1) - строка-1 (колонок-1)
  • строки-3 (колонок-2) = строка -3 (столбец-1) - строка-2 (колонка-1) и т. Д.

Позвольте мне показать вам, как выходной файл Шоуда быть как:

  Column-1 Column-2 

row-1 0   0 
row-2 25.00  25.00 
row-3 27.14  2.14 
row-4 29.29  2.15 
row-5 31.50  2.21 
row-6 33.57  2.07 

Сейчас я только здесь с программированием:

import sys 

with open('file.txt', "r") as f: 
    sys.stdout = open('%s (calc).txt' % f.name, 'a') 
    for line in f: 
     column = line.strip().split() 
     Column_1 = float(column[0]) 
     column.extend([None]) 

Интересно, что делать дальше. Может быть, numpy подходит для этой задачи? Я не силен в этом (в основном, я вообще этого не знаю), должен ли я это узнать?

В любом случае, я был бы очень благодарен вам за вклад.

+0

Посмотрите на Pandas 'roll_apply: http://pandas.pydata.org/pandas-docs/stable/comput.html#moving-rolling-statistics-moments – asiviero

ответ

5

Я считаю, что это будет делать то, что вы просили:

INPUT = 'file.txt' 
OUTPUT = 'calc.txt' 

def main(): 
    with open(INPUT, 'r') as reader, open(OUTPUT, 'a') as writer: 
     last_value = 0 
     for line in reader: 
      column_1, *remaining_columns = map(float, line.split()) 
      column_2 = column_1 - last_value 
      last_value = column_1 
      print(column_1, column_2, sep='\t', file=writer) 

if __name__ == '__main__': 
    main() 
+0

Вы можете упростить строку 8, используя 'column_1 = next (map (float, line.split())) ' –

+0

Это правда, но способ, которым он написан, заставляет проверять тип проверки на остальных столбцах. Приняв подход, было бы лучше написать 'column_1 = float (next (iter (line.split()))), так как карта не понадобилась. Поскольку строка 8 в настоящее время стоит, все столбцы будут проверяться на допустимые значения float. –

+0

Достаточно честный. Но OP использует 'float (line.split() [0])', который не дает указания на тип, содержащийся в других столбцах (если есть). Возможно, принуждение к тому, чтобы он плавал во всем мире, не будет делать этого с их входами. –

2

Одним из подходов может быть следующее: Скажем у вас есть два списка:

a = [1,2,3,0] 
b = [0,1,2,3] 

Вы можете вычесть один список из другого использования следующий этап:

import operator 
map(operator.sub, a, b) 

Для этого вам необходимо прочитать в своем файле как массив (usi ng array.append(value), чтобы получить все данные.

Затем сделайте копию своих данных и смещайте их на один (длина списка должна быть одинаковой). Как вы обрабатываете начало и конец массива, зависит от того, насколько важны эти значения для вас (возможно, вы можете позволить себе потерять одно значение).

+0

** celenius **, спасибо, я попробую) – Moveton

2

Вот решение, используя списочные и почтовый индекс:

#!/usr/bin/env python3 

with open('file.txt', "r") as f: 

    # read column one into a list 
    column_1 = [float(line.strip()) for line in f] 
    # compute differences of neighbouring values 
    column_2 = [now - last for now, last in zip(column_1, [0.0]+column_1[:-1])] 

    with open("result.txt", "w") as outfile: 
     for c1, c2 in zip(column_1, column_2): 
      print("{:.2f}\t{:.2f}".format(c1, c2), file=outfile) 

То, что здесь происходит, мы сначала создать список всех записей из входного файла. Используя zip, мы можем создавать кортежи из двух (или более) итераций. Мы должны создать второй список со значениями, сдвинутыми на 1, и добавив 0.0 спереди, чтобы действовать как контрольная единица для первой записи.

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

Изучение numpy - это всегда хорошая идея, но я думаю, что это будет излишним для этой задачи.

+0

** m00am **, спасибо, я попробую это. Что касается numpy - спасибо за совет, сделаем это позже, немного более уверенно в «общих» вещах :) – Moveton