WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

doppelte Zeilen eines cell array löschen

 

FrAnKy_0
Forum-Anfänger

Forum-Anfänger


Beiträge: 29
Anmeldedatum: 16.05.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.07.2018, 02:05     Titel: doppelte Zeilen eines cell array löschen
  Antworten mit Zitat      
Hallo Leute,

ich suche eine Funktion die es mir erlaubt doppelte Zeilen eines cell array zu löschen. Dabei können in den einzelnen Zellen strings, Matrizen oder Ziffern auftreten. Jedoch pro Spalte nur eine dieser drei Arten.
D.h in Spalte 1 z.B. nur strings, Spalte 2 nur Matrizen und Spalte 3 nur Ziffern.

Bspl.:
Code:
cell_array={[1 2 3; 4 5 6], [7]; [8 9 10; 11 12 13], [14];[1 2 3; 4 5 6], [7]}


Im Beispiel sind Zeile 1 und 3 gleich, eine von beiden soll gelöscht werden.

Hat jemand einen Lösungsansatz oder kennt sogar eine bereits existierende Funktion?

Danke und Gruß
Franky
Private Nachricht senden Benutzer-Profile anzeigen


DerElch
Forum-Anfänger

Forum-Anfänger


Beiträge: 21
Anmeldedatum: 18.07.18
Wohnort: Wien
Version: 2017b
     Beitrag Verfasst am: 25.07.2018, 07:48     Titel:
  Antworten mit Zitat      
Hallo Franky_0,

deine Beispieldaten unterscheiden sich von deiner Beschreibung.
Kannst du uns auch "echte" Beispieldaten geben?

Wie groß sind die Datensätze?

Was wird die hier aufgenommen? Ich tu mir leichter wenn ich den Sinn dieses Problems auch verstehe Wink
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 25.07.2018, 12:39     Titel: Re: doppelte Zeilen eines cell array löschen
  Antworten mit Zitat      
Hallo FrAnKy_0,

Code:
cell_array = {[1 2 3; 4 5 6], [7]; [8 9 10; 11 12 13], [14];[1 2 3; 4 5 6], [7]};
s = size(cell_array, 1);
keep = true(s, 1);
for i1 = 2:s
  c_i1 = cell_array(i1, :);
  for i2 = 1:i1 - 1
    if keep(i2) && isequal(c_i1, cell_array(i2, :))
      keep(i1) = false;
      break;   % Stop the for i2 loop
    end
  end
end
cleaned = cell_array(keep, :);


Wenn das Input Array groß ist, ist die quadratische Abhängigkeit von der Größe ein Problem. Dann könnte es effizienter sein, Hash-Werte für die einzelnen Zeilen zu bilden, z.B. mit https://www.mathworks.com/matlabcen.....leexchange/31272-datahash:
Code:
hash = cell(size(cell_array));
Opt = struct('Format', 'base64', 'Method', 'MD5');
for k = 1:size(cell_array, 1)
  hash{k} = DataHash(cell_array(k, :), Opt);
end

[~, index] = unique(hash);
cleaned = cell_array(index);

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
FrAnKy_0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 29
Anmeldedatum: 16.05.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 26.07.2018, 23:12     Titel:
  Antworten mit Zitat      
Danke Jan! Du warst wieder mal eine große Hilfe.
Genau das was ich gesucht habe und es klappt perfekt.

Gruß Franky
Private Nachricht senden Benutzer-Profile anzeigen
 
FrAnKy_0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 29
Anmeldedatum: 16.05.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.07.2018, 20:34     Titel: Re: doppelte Zeilen eines cell array löschen
  Antworten mit Zitat      
Hallo Jan,
ich habe den oberen Code in mein Programm eingebaut und es funktioniert genau so wie es soll. Nun kommt jedoch noch etwas dazu was erfüllt werden muss. Ich reserviere vor Programmstart den Speicher für das cell array. Durch das Eliminieren von doppelten Zeilen wird diese Reservierung jedoch zu Nichte gemacht und mein Programm wird langsamer. Außerdem würde ich dann gerne den Index der letzten gefüllten Zeile wiedergeben bekommen. Ohne Speicher Reservierung sieht dies wie folgt aus
Code:
s = size(Architektur, 1);
keep = true(s, 1);
for i1 = 2:s
  c_i1 = Architektur(i1, :);
  for i2 = 1:i1 - 1
    if keep(i2) && isequal(c_i1, Architektur(i2, :))
      keep(i1) = false;
      break;  
    end
  end
end
Architektur = Architektur(keep, :);

m=size(Architektur,1);
dabei ist m der gesuchte Zeilenindex.

Kennst du eine Möglichkeit den Speicher zu reservieren, dann die reservierte Größe beim löschen doppelter Zeilen beizubehalten (also nur die Inhalte der Zellen löschen) und mir den Zeilenindex der letzten gefüllten Zeile wieder zu geben?

Diese Anforderungen müssen erfüllt werden da diese Überprüfung auf doppelte Zeilen sozusagen nach jedem füllen einer Zeile abgerufen wird und nicht erst wenn das cell array komplett voll ist. Dies liegt daran das nebenher ein Ranking läuft welches das Ziel hat nur die besten 100 Zeilen zu speichern.

Gruß Franky
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 30.07.2018, 19:07     Titel: Re: doppelte Zeilen eines cell array löschen
  Antworten mit Zitat      
Hallo FrAnKy_0,

Ich verstehe die Frage nicht. Wo wird was reserviert und welcher Code wird langsamer?

Zitat:
Außerdem würde ich dann gerne den Index der letzten gefüllten Zeile wiedergeben bekommen.

Das funktioniert mit dem gezeigen size Befehl schon, oder?

Zitat:
Kennst du eine Möglichkeit den Speicher zu reservieren, dann die reservierte Größe beim löschen doppelter Zeilen beizubehalten (also nur die Inhalte der Zellen löschen) und mir den Zeilenindex der letzten gefüllten Zeile wieder zu geben?

Ich rate mal
Code:
Architektur(~keep, :) = {[]};
m = find(keep, 1, 'last')


Zitat:
Diese Anforderungen müssen erfüllt werden da diese Überprüfung auf doppelte Zeilen sozusagen nach jedem füllen einer Zeile abgerufen wird und nicht erst wenn das cell array komplett voll ist. Dies liegt daran das nebenher ein Ranking läuft welches das Ziel hat nur die besten 100 Zeilen zu speichern.


In dem Fall ist mein Code sowieso Quatsch, oder? Dann wäre es doch sinnvoll gleich beim Einfügen jeder neuen Zeile diejenige zu ersetzen, die am "schlechtesten" ist.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
FrAnKy_0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 29
Anmeldedatum: 16.05.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.07.2018, 19:52     Titel:
  Antworten mit Zitat      
Hallo Jan,

danke für die schnelle Antwort.

Mein Programm ist wie folgt aufgebaut:
Code:

Ranking=100;
Architektur=cell(Ranking,5);

% hier stehen dann Befehle die EINE Zeile (die m-te) von Architektur befüllen.

% --------------------------------------------------------------------------
% Löschen von doppelten Architekturen
% --------------------------------------------------------------------------
s = size(Architektur, 1);
keep = true(s, 1);
for i1 = 2:s
  c_i1 = Architektur(i1, :);
  for i2 = 1:i1 - 1
    if keep(i2) && isequal(c_i1, Architektur(i2, :))
      keep(i1) = false;
      break;  
    end
  end
end
Architektur(~keep, :) = {[]};  % dein neu geposteter Befehl damit die Größe von Architektur beibehalten bleibt. (bereits getestet => funktioniert)


m=size(Architektur,1); % gibt mir ja dann entsprechend m=100 zurück
m = find(keep, 1, 'last'); % gibt mir nicht die richtige Zahl wieder da die leeren Zellen ebenfalls als doppelte Zeilen von Architektur angesehen werden.

m = find(keep, 1, 'last')-2; % passt bei einem ausgewählten Beispiel, dies müsste ich aber noch auf Richtigkeit überprüfen.

%--------------------------------------------------------------------------
%Ranking
%--------------------------------------------------------------------------
   
   if m == Ranking+1
   
   Architektur= sortcell(Architektur, [4 3]);
   %sortiert nach 4ter und dann nach 3ter spalte
   
   Architektur(m,:)=[]; % 101 Zeile wird entfernt

% hier überlege ich ob es nicht sinnvoller ist 101 Zeilen am Anfang des Programms zu reservieren und diese dann nur zu leere anstatt zu löschen.

        m=m-1;
   
   end
 
% -----------------------------------------------------------------------
   
   m=m+1;
   



 


Wenn ich dich richtig verstanden habe ist dein Vorschlag die m-te Architektur nicht gleich zu Speichen sondern zu schauen ob sie doppelt ist und anschließend das Ranking so durchzuführen das die "schlechteste" Architektur von der m ten Architektur (wenn sie denn "besser" ist) überspeichert wird?

Wenn der code soweit nachvollziehbar ist und verbesserungswürdige Stellen auffallen würde ich mich auch sehr über Hinweise darauf freuen.

Gruß Franky
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.