2015-09-10 4 views
5

Ich bin ein Anfänger in Python und kann nicht mit einer der Momente meines Projekts fertig zu werden, so würde ich mich freuen, Sie, mir zu helfen :)Python - Die Berechnung der zweiten Spalte von der ersten in einer Datei

Letss vorstellen, ich habe eine * .txt-Datei mit nur einer Spalte, die wie folgt aussieht:

  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 

* Spalte mit Zeilen wird hier nur hinzugefügt, um die Erläuterung zu vereinfachen.

Ich muss die zweite Spalte berechnen, die als Eingangsdaten von der Spalte-1 nimmt und das Ergebnis der Subtraktion dieses Zeilenwerts von der vorherigen (wenn der Zeile-1 (Spalte-1) Wert 0 ist), als es sollte 0 in der Zeile-1 (Spalte-2) auch sein). Es sollte sein wie:

  • row-2 (Column-2) = row-2 (Column-1) - row-1 (Column-1)
  • row-3 (Column-2) = Zeilen -3 (Spalte-1) - Zeile-2 (Spalte-1) und so weiter.

Lassen Sie mich Ihnen zeigen, wie die Ausgabedatei wie sein shoud:

  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 

Denn jetzt bin ich nur hier mit meiner Programmierung:

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]) 

Ich frage mich, was als nächstes zu tun ist. Vielleicht ist Numpy für diese Aufgabe richtig? Ich bin nicht stark darin (grundsätzlich weiß ich es überhaupt nicht), sollte ich es lernen?

Wie auch immer, ich wäre wirklich dankbar für Ihren Beitrag.

+0

einen Blick auf Pandas' Take rolling_apply: http://pandas.pydata.org/pandas-docs/stable/computation.html#moving-rolling-statistics-moments – asiviero

Antwort

5

Ich glaube, das tun würde, was Sie gefragt:

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

Sie 8 vereinfachen Zeile mit 'Spalte_1 = next (map (float, line.split())) ' –

+0

Das stimmt, aber die Art, wie es geschrieben wird, erzwingt die Überprüfung der übrigen Spalten. Bei näherer Betrachtung wäre es besser, 'column_1 = float (next (iter (line.split())))' 'zu schreiben, da die Karte nicht benötigt würde. Da Zeile 8 derzeit steht, werden alle Spalten als gültige Float-Werte überprüft. –

+0

Fair genug. Aber OP verwendet 'float (line.split() [0])', was keinen Hinweis auf den Typ gibt, der in anderen Spalten enthalten ist (falls vorhanden). Vielleicht wird es durchsetzen, dass es überall fließt, und es wird es nicht mit ihren Eingaben machen. –

2

Ein Ansatz, die folgende sein: Angenommen, Sie zwei Listen haben:

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

Sie dann eine Liste von dem anderen subtrahieren kann mit der folgende Schritt:

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

Um dies zu tun, müssten Sie Ihre Datei als ein Array (usi ng array.append(value), um alle Daten zu erhalten.

Dann erstellen Sie eine Kopie Ihrer Daten, und versetzen Sie sie um eins (die Listenlänge muss gleich sein). Wie Sie mit dem Anfang und dem Ende des Arrays umgehen, hängt davon ab, wie wichtig diese Werte für Sie sind (vielleicht können Sie es sich leisten, einen Wert zu verlieren).

+0

** celenius **, danke, ich werde es versuchen) – Moveton

2

Hier ist eine Lösung mit Listenkomprehensionen und eine Zip:

#!/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) 

Was passiert hier ist, dass wir zunächst eine Liste aller Einträge aus der Eingabedatei erstellen. Mit zip können wir Tupel aus zwei (oder mehr) Iterablen erzeugen. Wir müssen eine zweite Liste mit den um 1 verschobenen Werten erstellen und eine 0.0 an der Vorderseite hinzufügen, um als Sentinel für den ersten Eintrag zu fungieren.

Jetzt können wir diese zwei Listen zusammenfügen und die Unterschiede zwischen den Wertpaaren mit dem zweiten Listenverständnis berechnen.

Lernen numpy ist immer eine gute Idee, aber ich denke, es wäre für diese Aufgabe übertrieben.

+0

** m00am **, danke, ich werde das versuchen. Wie für die numpy - danke für die Beratung, wird es später tun, nachdem Sie ein bisschen mehr Vertrauen in 'gemeinsame' Dinge :) – Moveton

Verwandte Themen