2017-07-21 1 views
0

Ich habe eine extrem große Datei von Tab-getrennte Werte von 10000 + Werte. Ich versuche, die Durchschnittswerte jeder Zeile in den Daten zu finden und diese neuen Werte an eine neue Datei anzufügen. Werte, die nicht gefunden wurden, werden jedoch in der großen Datei als -1 eingegeben. Die Verwendung der -1-Werte bei der Berechnung meiner Durchschnittswerte führt zu einem Datenverlust. Wie kann ich diese Werte ausschließen? Die große Dateistruktur wie folgt aussieht:Berechnen Sie, während -1 ausschließt

"HsaEX0029886" 100 -1 -1 100 100 100 100 100 100 -1 100 -1 100 
"HsaEX0029895" 100 100 91.49 100 100 100 100 100 97.87 95.29 100 100 93.33 
"HsaEX0029923" 0 0 0 -1 0 0 0 0 0 9.09 0 5.26 0 

In meinem Code Im die letzten drei Elemente zu nehmen und den Durchschnitt nur die drei Werte zu finden. Hier ist meine gesamte Code Wenn die letzten drei Elemente in der Reihe 85 sind, 12, und -1, muss ich den Durchschnitt von 85 und 12 zurück:

with open("PSI_Datatxt.txt", 'rt') as data: 
    next(data) 
    lis = [line.strip("\n").split("\t") for line in data]  # create a list of lists(each row) 
for row in lis: 
    x = float(row[11]) 
    y = float(row[12]) 
    z = float(row[13]) 
    avrg = ((x + y + z)/3) 
    with open("DataEditted","a+") as newdata: 
     if avrg == -1: 
      continue #skipping lines where all 3 values are -1 
     else: 
      newdata.write(str(avrg) + ' ' + '\n') 

Dank. Kommentar, wenn eine Klärung erforderlich ist.

+0

so dass, wenn eine Linie 10 Werte tun sollten, ist, und Zwei von ihnen sind -1, was machen wir? Ersetzen Sie -1 durch 0 und machen Sie avg = sum (row)/10, oder ignorieren wir sie und machen avg = sum (row)/8? – jacoblaw

+0

Ihre Einrückung ist deaktiviert. Warum nehmen Sie nur einen Wert aus jeder Zeile? –

+0

1) Sie müssen die Datei nach dem Öffnen nicht suchen, es ist bereits am Anfang; 2) es gibt keine Notwendigkeit, die zweite Datei zu schließen, da die 'with'-Klausel das für Sie erledigt; 3) Ihre Einrückung ist wahrscheinlich ausgeschaltet, da Ihr Code im aktuellen Zustand nur den Durchschnitt für eine Zeile – ForceBru

Antwort

1
data = [float(x) for x in row[1:] if float(x) > -1] 
    if data: 
     avg = sum(data)/len(data) 
    else: 
     avg = 0 # or throw an exception; you had a row of all -1's 

Die erste Zeile ein ziemlich Standard Pythonism ist ... ein Array gegeben (in diesem Fall Reihe), können Sie durch die Liste durchlaufen und wenn die Bedingung Bit in dem Feld für x, indem Sie das Material herauszufiltern.

Wenn man sich die letzten drei Werte, nur aussehen wollte von meinen Sie haben zwei Möglichkeiten, je nachdem, was Sie letzten drei:

data = [float(x) for x in row[-3:] if float(x) > -1] 

aussehen wird auf der letzten 3 und gegeben Sie 0 bis 3 Werte zurück abhängig davon, ob sie -1 sind.

data = [float(x) for x in row[1:] if float(x) > -1][:-3] 

werden Sie bis 3 der letzten „guten“ Werte geben (wenn Sie alle oder fast alle -1 für eine bestimmte Zeile haben, wird es weniger als 3)

+0

x> -1 ignoriert gültige negative Daten. –

+0

Danke Leute ihr bläst meine Gedanken ich werde diese versuchen! –

+0

@ cᴏʟᴅsᴘᴇᴇᴅ die Sample-Daten zumindest hatten nur -1 und nicht-negative Zahlen und ich mag float (x) == -1 nicht tun. Für OP: gehen Sie zu bearbeiten, um ein wenig mehr zu erklären, und auch für Ihre letzten Werte erhalten Frage – Foon

1

Hier ist es in das gleiche Format wie deine ursprüngliche Frage. Es bietet Ihnen eine Fehlermeldung zu schreiben, wenn die Zeile nur Nullen ist, oder Sie können es stattdessen ignorieren und schreiben nichts

with open("PSI_Datatxt.txt", 'r') as data: 
    for row in data: 
     vals = [float(val) for val in row[1:] if float(val) != -1] 
     with open("DataEditted","a+") as newdata: 
      try: 
       newdata.write(str(sum(vals)/len(vals)) + ' ' + '\n') 
      except ZeroDivisionError: 
       newdata.write("My Error Message Here\n") 
1

Dieses es

import csv 


def average(L): 
    L = [i for i in map(float, L) if i != -1] 
    if not L: return None 
    return sum(L)/len(L) 


with open('path/to/input/file') as infile, open('path/to/output/file', 'w') as fout: 
    outfile = csv.writer(fout, delimiter='\t') 
    for name, *vals in csv.reader(infile, delimiter='\t'): 
     outfile.writerow((name, average(vals)) 
Verwandte Themen