2017-06-27 2 views
0

Ich habe einen Prozess, der während der Woche generierte Berichte sammelt und die Sammlung konsolidiert, um identische Berichte zu eliminieren.So finden Sie effizient identische Indizes in mehreren Datenrahmen

Ich habe eine Funktion geschrieben, die identische Berichte identifiziert, indem sie diejenigen findet, die identische Indizes haben, dann schließt sie alle außer einem von denen aus, die identisch sind und sich fortbewegen. Während es für 5000-10.000 Berichte gut funktioniert, dauert es sehr viel Zeit, um über 50.000 Berichte zu verarbeiten, die im Laufe der Zeit immer häufiger werden.

Es wäre nett, wenn ich die Berichte präventiv eliminieren könnte und so diesen Schritt vermeiden könnte, aber der Prozess der Generierung der Berichte lässt das nicht zu. Also, ich möchte einen Weg finden, um diese oder eine ähnliche Funktion effizienter zu machen.

Der Code ist unten, jede Hilfe und Ideen würden sehr geschätzt werden !!

def report_diff_index(self,dnc_data,folders): 
    master_report_dict, master_val_dict = self.report_orderer(folders) 
    sorts = self.report_sorter(dnc_data,master_report_dict) 
    keys = [k for k in sorts.keys()] 
    consolidated_sorts = keys 
    print('Original Report Size: ', len(consolidated_sorts)) 
    for k in keys: 
     if k in consolidated_sorts: 
      for j in keys[keys.index(k)+1:]: 
       if j in consolidated_sorts: 
        if len(list(set(sorts[k].index).symmetric_difference(sorts[j].index))) == 0: 
         consolidated_sorts.remove(j) 
    print('Consolidated Report Size: ', len(consolidated_sorts)) 
    consolidated_report = {} 
    consolidated_val = {} 
    for s in consolidated_sorts: 
     consolidated_report[s] = master_report_dict[s] 
     consolidated_val[s] = master_val_dict[s] 
    return consolidated_report, consolidated_val 

Antwort

1

Ich weiß nicht, ob ich das richtig das Problem zu verstehen, und auch wenn ich tun, ich weiß nicht, ob dies ist schneller , aber wäre es nicht möglich, ein Diktat zu erstellen, in dem Sie den eindeutigen Berichtsindex als Schlüssel verwenden (z. B. frozenset) und dann den Berichtsschlüssel als Wert verwenden. Es fühlt sich an wie ein schneller Weg, um die einzigartige Liste zu erstellen, aber ich kann aus sein:

def report_diff_index(self,dnc_data,folders): 
    master_report_dict, master_val_dict = self.report_orderer(folders) 
    sorts = self.report_sorter(dnc_data,master_report_dict) 
    print('Original Report Size: ', len(sorts)) 
    unique_reports = dict() 
    for report_key, report in sorts.items: 
     key = frozenset(report.index) 
     # Alt 1. Replace with new (identical) repoirt 
     unique_reports[key] = report_key 
     # Alt 2. Keep first report 
     if key not in unique_reports: 
      unique_reports[key] = report_key 
    consolidated_sorts = unique_reports.values() 
    print('Consolidated Report Size: ', len(consolidated_sorts)) 
    consolidated_report = {} 
    consolidated_val = {} 
    for s in consolidated_sorts: 
     consolidated_report[s] = master_report_dict[s] 
     consolidated_val[s] = master_val_dict[s] 
    return consolidated_report, consolidated_val 

Wie Sie sehen können, gibt es auch zwei Optionen im dict Update ist, die davon abhängt, ob der erste behalten möchten gefunden Bericht oder wenn es egal ist.

Die Einfügung in ein Diktat sollte sich O (1) nähern, daher würde ich mir vorstellen, dass dies ziemlich schnell ist.

+0

Danke! Kannst du einen Pandas-Dataframe-Index als Diktatschlüssel verwenden? Ich werde es ausprobieren .. – Dorian821

+0

Sie können es nicht direkt verwenden, aber alle unveränderlichen, d. H. Hashable, Daten können als Schlüssel verwendet werden. 'set's und' list's sind veränderbar, also nicht verwendbar als dict 'key's aber' frozenset' und 'tuple's sind unveränderlich und können somit verwendet werden. Wenn Sie Ihre Indizes in eingefrorene Mengen umwandeln, können Sie sie als Schlüssel verwenden. – JohanL

+0

@ Dorian821 Hast du das zur Arbeit gebracht? – JohanL

0

Korrigieren Sie mich, wenn ich falsch bin, aber es sieht aus wie alles in:

consolidated_sorts = keys 
print('Original Report Size: ', len(consolidated_sorts)) 
for k in keys: 
    if k in consolidated_sorts: 
     for j in keys[keys.index(k)+1:]: 
      if j in consolidated_sorts: 
       if len(list(set(sorts[k].index).symmetric_difference(sorts[j].index))) == 0: 
        consolidated_sorts.remove(j) 

ist nur über einzigartige Berichte zu finden. Tatsächlich sind die Iterationen redundant, weil Sie zuerst consolidated_sorts gleich keys setzen, dann diese Werte iterieren und fragen, ob sie sich in consolidated_sorts befinden, woher sie kommen.

Wenn Sie einfach eindeutige Schlüssel möchten, können Sie so etwas wie dies versuchen:

def report_diff_index(self,dnc_data,folders): 
    master_report_dict, master_val_dict = self.report_orderer(folders) 
    sorts = self.report_sorter(dnc_data,master_tree) 

    # New code to create unique set of keys 
    unique_keys = set(sorts.keys()) 

    consolidated_report = {} 
    consolidated_val = {} 

    for key in unique_keys: 
     consolidated_report[key] = master_report_dict[key] 
     consolidated_val[key] = master_val_dict[key] 

    return consolidated_report, consolidated_val 
+0

Danke, aber das Problem besteht nicht darin, eindeutige Schlüssel zu finden, sondern darin, eindeutige Indizes für die Werte im Wörterbuch zu finden. Deshalb vergleiche ich Werte miteinander. – Dorian821

+0

Verwenden Sie ein 'geordnetes Diktat', von dem Sie glauben, dass Ihr Diktat Indizes hat? Oder wie ist dein "Diktat" strukturiert? Außerdem bin ich überrascht, dass dieser Code derzeit für Sie funktioniert. Was verstehen Sie unter dieser Zeile? 'If len (list (set (Sortierung [k] .index) .symmetric_difference (Sortierung [j] .index))) == 0:'? – jack6e

+0

@ jack6e Nicht, dass ich Dorian821 bin, aber diese Zeile wird, wenn auch etwas erfunden, die beiden Listen von Berichtschlüsseln vergleichen und auf Gleichheit prüfen, unabhängig von der Schlüsselreihenfolge in den Listen. Ich würde mir vorstellen, dass ein einfaches 'set (sortier [k] .index) == set (sortiert [j] .index)' mehr Sinn machen würde, aber das Ergebnis sollte dasselbe sein. – JohanL

Verwandte Themen