Ich renne in ein Problem, das ich noch nie zuvor gesehen habe, und es ist verdammt frustrierend von mir. Ich verwende rpy2
, um mit R
aus einem Python-Skript zu interferieren und ein Array zu normalisieren. Aus irgendeinem Grund, wenn ich meine Ausgabe zusammen stücken und in eine Datei drucken, dauert es Alter zu drucken. Es verlangsamt sich auch, wenn es weitergeht, bis es tropft vielleicht ein paar kb Daten pro Minute ausgeben.Python unglaublich langsam drucken
Meine Eingabedatei ist groß (366 MB), aber diese läuft auf einem Hochleistungsrechencluster mit nahezu unbegrenzten Ressourcen. Es sollte kein Problem haben, das durchzuspielen.
Hier ist, wo ich tatsächlich die Normalisierung tun:
matrix = sample_list # two-dimensional array
v = robjects.FloatVector([ element for col in matrix for element in col ])
m = robjects.r['matrix'](v, ncol = len(matrix), byrow=False)
print("Performing quantile normalization.")
Rnormalized_matrix = preprocessCore.normalize_quantiles(m)
normalized_matrix = np.array(Rnormalized_matrix)
Wie Sie sehen können, habe ich mit einem numpy.array
Objekt am Ende meine jetzt normalisierte Daten enthält. Ich habe eine andere Liste, die andere Zeichenketten enthält, die ich auch zum Ausgang drucken möchte, jedes Element, das einem Element des numpy Feldes entspricht. Ich wiederhole also, indem ich jede Zeile des Arrays zu einer Zeichenkette zusammenfüge und beide zur Ausgabe drucke.
for thing in pos_list: # List of strings corresponding with each row of array.
thing_index = pos_list.index(thing)
norm_data = normalized_matrix[thing_index]
out_data = "\t".join("{0:.2f}".format(piece) for piece in norm_data)
print(thing + "\t" + out_data, file=output)
Ich bin kein Profi, aber ich habe keine Ahnung, warum die Dinge so sehr verlangsamen. Jeder Einblick oder Vorschläge wären sehr, sehr geschätzt. Ich kann mehr/den Rest des Skripts posten, wenn jemand denkt, dass es hilfreich sein könnte.
Update: Danke an @lgautier für seinen Profilierungsvorschlag. Unter Verwendung des line_profiler
Modul, konnte ich mein Problem mit der Leitung lokalisieren: thing_index = pos_list.index(thing)
Dies macht Sinn, da diese Liste ist sehr lang, und es erklärt auch die Verlangsamung als das Skript abläuft. Stattdessen wurde einfach das Problem behoben.
Profilieren von Original-Code (das% für die angegebene Zeile bemerken):
Line # Hits Time Per Hit % Time Line Contents
115 1 16445761 16445761.0 15.5 header, pos_list, normalized_matrix = Quantile_Normalize(in
117 1 54 54.0 0.0 print("Creating output file...")
120 1 1450 1450.0 0.0 output = open(output_file, "w")
122 1 8 8.0 0.0 print(header, file=output)
124 # Iterate through each position and print QN'd data
125 100000 74600 0.7 0.1 for thing in pos_list:
126 99999 85244758 852.5 80.3 thing_index = pos_list.index(thing)
129 99999 158741 1.6 0.1 norm_data = normalized_matrix[thing_index]
130 99999 3801631 38.0 3.6 out_data = "\t".join("{0:.2f}".format(piece) for pi
132 99999 384248 3.8 0.4 print(thing + "\t" + out_data, file=output)
134 1 3641 3641.0 0.0 output.close()
neuen Code Profilierungs:
Line # Hits Time Per Hit % Time Line Contents
115 1 16177130 16177130.0 82.5 header, pos_list, normalized_matrix = Quantile_Normalize(input_file, data_start)
116
117 1 55 55.0 0.0 print("Creating output file...")
118
119
120 1 26157 26157.0 0.1 output = open(output_file, "w")
121
122 1 11 11.0 0.0 print(header, file=output)
123
124 # Iterate through each position and print QN'd data
125 1 1 1.0 0.0 count = 0
126 100000 62709 0.6 0.3 for thing in pos_list:
127 99999 58587 0.6 0.3 thing_index = count
128 99999 67164 0.7 0.3 count += 1
131 99999 85664 0.9 0.4 norm_data = normalized_matrix[thing_index]
132 99999 2877634 28.8 14.7 out_data = "\t".join("{0:.2f}".format(piece) for piece in norm_data)
134 99999 240654 2.4 1.2 print(thing + "\t" + out_data, file=output)
136 1 1713 1713.0 0.0 output.close()
Enthält pos_list R-Objekte? Ich verwende rpy2 nicht häufig, aber aus meiner Erfahrung sind die Interaktionen zwischen den beiden Sprachen ziemlich langsam. –
Welcher Teil ist eigentlich langsam? Versuchen Sie, Teile auskommentieren, um zu sehen, was es schneller macht. Ich würde erwarten, dass [Element für Spalte in Matrix für Element in Spalte] 'ziemlich langsam ist. –
Nein, 'pos_list' enthält nur Zeichenfolgen. Das '[Element für Spalte in Matrix für Element in Spalte]' Bit ist langsam, aber es ist vor jeder tatsächlichen Ausgabe in Datei, so ist es hier nicht der Flaschenhals. –