AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Häufigkeiten und Kreuztabellen aus zweidimensionalem Array errechnen
Thema durchsuchen
Ansicht
Themen-Optionen

Häufigkeiten und Kreuztabellen aus zweidimensionalem Array errechnen

Ein Thema von Benmik · begonnen am 25. Aug 2017 · letzter Beitrag vom 11. Sep 2017
Antwort Antwort
Benmik

Registriert seit: 11. Apr 2009
570 Beiträge
 
Delphi 12 Athens
 
#1

Häufigkeiten und Kreuztabellen aus zweidimensionalem Array errechnen

  Alt 25. Aug 2017, 22:36
Ich habe eine Datenbank, aus der ich Häufigkeiten und Kreuztabellen (mit zwei, aber auch drei Variablen) mittels SQL ermittle.

Ich möchte jetzt das Ganze auf reines Delphi reduzieren, die Datenbank als zweidimensionales Array (ca. 250 Felder, ca. 3000 Datensätze) abbilden und die SQL-Befehle nachbauen.

Die Algorithmen für diese SQL-Befehle suche ich jetzt.
Bei einer einfachen Häufigkeit würde ich zum Beispiel die 3000 Werte des betreffenden Feldes in ein eindimensionales Array kopieren und das Array dann mittels Quicksort sortieren.
Aber vielleicht gibt es hierfür und vor allem für eine Kreuztabelle mit 2 und 3 Variablen schon fertige Lösungen?

Eigentlich müsste doch auch eine Sortierfunktion reichen, die ein zweidimensionales Array nach 3 Feldern sortieren kann?

Geändert von Benmik (25. Aug 2017 um 22:59 Uhr)
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#2

AW: Häufigkeiten und Kreuztabellen aus zweidimensionalem Array errechnen

  Alt 26. Aug 2017, 19:10
Vielleicht kannst Du etwas präziser beschreiben, welche Dimension Du als Ausgangssituation hast und was es werden soll.
Aus Deiner Beschreibung wird mir nicht so richtig klar, was IST ist und was SOLL soll.

Und auch wenn es nicht die Frage war:
Was ist der Anlass? Warum nicht SQL? Es gibt ein paar DB, die das ganz gut können, Statistik dann sowieso.

Der Ausgangspunkt einer Kreuztabelle wäre für mich bspw. eine Tabelle mit konkreten ID (Primärschlüssel), einer Kategorie/Referenz und einem Wert. Davon hätte ich vielleicht 3000 Datensätze, mit 250 Referenzen/Kategorien. Als Kreuztabelle ergäbe das 250 Spalten mit ein paar Zeilen.
Gruß, Jo
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
570 Beiträge
 
Delphi 12 Athens
 
#3

AW: Häufigkeiten und Kreuztabellen aus zweidimensionalem Array errechnen

  Alt 27. Aug 2017, 10:09
Hallo jobo, bin etwas erstaunt, dachte, die Fragestellung wäre recht einfach. Irrtum offenbar.

Es geht um ein Auswertprogramm für eine jährliche Datenerhebung, die seit über 10 Jahren läuft. Sie liegt im DBF-Format vor. Ich lese sie mit TDbf ein (dessen Aktualisierung schon nervig genug ist) und werte die Abfragen mit AbsoluteDatabase aus (da AbsDB In-Memory-Tables bietet). Das klappt alles einwandfrei.

Jetzt würde ich mich gern unabhängig von AbsDB machen, dessen umfangreiche DB-Funktionalität ich überhaupt nicht brauche. Die Daten sind statisch und werden ausschließlich gelesen (außer beim Einlesen der DB), und Mehrbenutzer ist auch nicht notwendig.

Hauptgrund ist aber die jährliche Aktualisierung. Die Erhebung wird jedes Jahr etwas verändert. Die Variablennamen werden nach Gruppen geordnet fortlaufend nummeriert. Fällt auch nur eine Variable weg oder wird hinzugefügt, ändert sich die Bezeichnung aller nachfolgenden. Dieses Jahr ist die 4. Variable weggefallen. Jetzt stehe ich vor nervtötenden Aufgabe, 100 Variablennamen, Bezeichnungen und Wertebezeichnungen neu anzupassen. (Auf die Struktur der DB habe ich keinerlei Einfluss).

Daher habe ich mich entschlossen, die lang gehegte Absicht anzugehen, das Programm generisch zu gestalten. Hierfür habe ich ein Konzept, das funktionierten müsste. Dazu brauche ich volle Gestaltung, was mit einem DB-Programm nicht möglich ist.

Ich habe keine Ahnung, nach welchem Algorithmus die SQL-Befehle von AbsDB arbeiten. Ich habe mich entschlossen, einfach die Kirche im Dorf zu lassen. Einfache Zähl- und Sortiervorgänge auch von einer Million Daten sind selbst bei älteren Prozessoren dermaßen schnell, dass auch deutlich suboptimale Algorithmen unter einer Sekunde brauchen. Das reicht völlig.

Ich kam dann relativ rasch darauf, dass bei diesem Ansatz das Problem darin besteht, ein zweidimensionales Array zu sortieren. In VB kein Problem, in Delphi augenscheinlich schon! Ich habe mich dann - wie so oft - nach diesem Beitrag von Altmeister David Heffernan gerichtet.

Mein Ansatz ist also bisher folgender:

1. Deklaration einer Klasse mit einem TStringDynArray als einzigem Inhalt (= Datensatz)
2. Deklaration einer Klasse TObjectList vom obigen Typ.
3. Einlesen der DBF-Daten über TDbf als string (ja, ja!)

Das Einlesen per TDbf, Überführen in die Liste inklusive Umwandeln zu string sowie testweise Sortieren nach einer Integervariable (mit 3.000 Mal Umwandeln von string zu integer im Comparer) dauert keine Sekunde auf einem Notebook mit einem älteren i3. Feierabend!

Mein weiteres Vorgehen wäre jetzt so, dass ich sortiere, zähle und das Ergebnis in die Form bringe, die mir zurzeit von SQL geliefert wird, damit ich den bisherigen Code nahtlos weiterverwenden kann. Bei Kreuztabellen mit 2 oder gar 3 Variablen würde ich dann immer die erforderlichen kleinen Abschnitte der Liste in eine temporäre Arbeitsliste kopieren, sortieren und zählen. Einfacher wäre es vermutlich, Quicksort den Bereich des zu Sortierenden zu übergeben, aber dann müsste ich direkt auf Quicksort gehen. Da nur die Referenzen kopiert werden und alles im Arbeitsspeicher abläuft, gehe ich davon aus, dass das so blitzschnell vor sich geht, dass auch diese Suboptimalität keine praktischen Konsequenzen hat.

Das ist jetzt mein Stand. Alles etwas vom Hobbyhandwerker, aber wenn's funktioniert?
Wenn natürlich jemand mit einer Profilösung um die Ecke kommt - herzlich willkommen!
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#4

AW: Häufigkeiten und Kreuztabellen aus zweidimensionalem Array errechnen

  Alt 28. Aug 2017, 12:32
Ich vermute so wie du den Begriff Variable benutzt, meinst du eigentlich Feldname.
Variablennamen sind für Anwender nicht sichtbar.

Warum sind andere Feldnamen für dich ein Problem?
Kannst du ein bischen Beispielcode zeigen, vor und nach deiner Umbenennung (Ist und Soll).

Mir erschließt sich nicht, wie eine Abkehr von SQL dein Problem lösen soll.
Insbesondere wenn du SQL-Befehle selbst implementieren willst.
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
570 Beiträge
 
Delphi 12 Athens
 
#5

AW: Häufigkeiten und Kreuztabellen aus zweidimensionalem Array errechnen

  Alt 29. Aug 2017, 19:35
Gut, dann beschreibe ich den typischen Fall:

Im ersten Jahr sieht der Fragebogen so aus:

1. Wie alt sind Sie (Jahre)?
2. Wie groß sind Sie (cm)
3. Welches Geschlecht haben Sie (m/w)?
4. Wie lautet Ihre PLZ?
5. Wieviele Personen leben in Ihrem Haushalt
a) Erwachsene?
b) Kinder?

Dies führt zu folgenden Feldnamen: V01,V02,V03,V04,V05a,V05b. Den vorhandenen Feldern wird von mir ein weiteres namens "Altersgruppe" hinzugefügt, dessen Werte aus der Variable (sic!) "V01" errechnet wird.

Im nächsten Jahr fällt das Feld "Alter" aus Diskriminierungsgründen weg. Das Feld "Geschlecht" hat nun die möglichen Werte "so genannt weiblich, so genannt männlich, Transgender, weiß nicht, sage ich nicht, Sonstiges", zudem heißt es nun "Sexuelle Orientierung". Außerdem rückt es an die erste Stelle und wird zu V01. Die Feldernamen heißen nun V01,V02,V03,V04a,V04b - mit nun zum Teil anderen Feldbezeichnungen, Wertbezeichnungen, Wertstrukturen.

Im Jahr darauf wird statt der PLZ das Bundesland abgefragt. Die Wertbezeichungen ändern sich von Bezeichnung gleich Wert zum Namen der 16 Bundesländer, der Typ von Integer zu string. Aus Layoutgründen rückt das Feld an die zweite Stelle. Das Alter wird nun wieder abgefragt, da herausgekommen ist, dass sich 18- und 80-Jährige trotz allem doch unterscheiden. Das Feld "Sexuelle Orientierung" heißt nun "Sexuelle Ichbestimmung" und erhält zusätzlich ein alphanumerisches Freifeld, das Feld wird daher in a) und b) erweitert. Die Körpergröße wird nun auf 0,5 cm genau abgefragt, der Typ ändert sich von Integer zu Float. Das Layout und damit die Reihenfolge der Felder wird komplett geändert, die Feldnamen damit auch. Die errechneten Felder - von denen es mehr gibt als in der DB sind - müssen aus immer wieder anders bezeichneten Feldern bestimmt werden.

Natürlich muss das Programm alle Datenbanken aller Jahre einlesen und richtig verarbeiten und alles richtig bezeichnen können. Tut es auch, weil ich einfach für jedes Jahr einen kompletten Satz von Bezeichnungen und Berechnungen erstellt habe. Ändert sich das drittletzte Feld, ist das Leben leicht. Fallen - wie in diesem Jahr - von den ersten 10 Feldern 5 weg, wird es bitter.

Ich habe mir daher ein System überlegt, wie ich gleichbleibende Felder (fast immer >95%) nur einmal beschreibe und der Position in der DB zuordne, egal wie sich der Feldname geändert hat. Ändert sich ein Feld, erstelle ich eine neue Beschreibung. In jedem Jahr muss ich nun nur die richtige Beschreibung der Position in der DB zuweisen, gleichbleibende Abschnitte (meist 90% ) kann ich einfach kopieren.

Ich frage mich nur, wo die tausend anderen Leute sind, die doch genau das gleiche Problem haben müssen.
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#6

AW: Häufigkeiten und Kreuztabellen aus zweidimensionalem Array errechnen

  Alt 29. Aug 2017, 20:11
das letzt genannte riecht doch ganz stark nach dem Grundsatz-Workflow "1. Typisieren", "2. Klassifizieren", "3. Normalisieren", "4.Anylsieren", "5.Auswerten"

Erst DANN/SO kann man ja eh überhaupt absolute numerische oder binäre Regeln ala Normal-Values/Ranges anwenden...
So aufbereitet kümmern sich um die DetailAnalyse dann aber besser SVMs (SupportVectorMaschines) oder wenn man Zeit hat auch NNs (NeuronaleNetze möglichst mit endlicher aber dafür kontinuierlicher BackPropagation!).

Solche Sachen per letzendlicher Kreuztablellen rein zweidimensional angehen zu wollen nenne ich mal "sportlichen Ehrgeiz"... wenn es klappt HURRA, dann veröffentlichen und kassieren!

Geändert von mensch72 (29. Aug 2017 um 20:17 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz