Stuttgart, den 27. Januar 2004
An alle !
Notiz zum Exportproblem
-----------------------
Als Exportproblem bezeichne ich hier die Aufgabe, aus einem Notebook Zahlen
in einem bestimmten Zahlenformat in eine Datei zu exportieren.
Die folgende Notiz zum Exportproblem entstand aus der Notwendigkeit, dieses
Problem fuer ein kleines MMa-Projekt selbst zu loesen. Sie verbindet die
Ergebnisse von systematischen Tests und das Ergebnis von Nachdenken ueber
dieses Problem.
Export
------
Die Export-Funktion ist sehr vielseitig, wie Help sagt :
Export can handle numerical and textual data, graphics, sounds, and
material from notebook.
Um das Exportproblem - wie oben definiert - zu loesen, ist es notwendig,
sich die vorhergehenden Verarbeitungsschritte in MMa genauer anzusehen.
Details zur Problemformulierung
-------------------------------
Die Eingabedaten seien erst einmal
liste = { 1, 1.2, 1.34, 1.234, 1.23456 } .
In einer Ausgabedatei sollen diese Zahlen auf _drei_ Stellen nach dem Komma
erscheinen.
Diese Forderung kann schon auf wenigstens zwei Weisen interpretiert werden
:
listeOutput1 = { 1, 1.2, 1.34, 1.234, 1.235 }
oder
listeOutput2 = { 1.000, 1.200, 1.234, 1.235 } .
Man muss sich erst klarmachen, welche Forderung man genau stellt.
Datenformatierung
-----------------
Hier sollen die Unterschiede zwischen NumberForm[ expr, n ] und PaddedForm[
.. ] herausgestellt werden :
------
NumberForm[ expr, n ] prints with approximate real numbers in expr given to
n-digit precision.
NumberForm[ expr, {n,f} ] prints with approximate real numbers having n
digits, with f digits right of the decimal point.
NumberForm works on integers as well as approximate numbers.
------
PaddedForm[ expr, n ] prints with all numbers in expr padded to leave room
for a total of n digits.
PaddedForm[ expr, {n,f} ] prints with approximate real numbers having
exactly f digits to the right of the decimal point.
By default, PaddedForm pads with spaces on the left to leave room for n
digits.
PaddedForm pads with zeros on the right in approximate real numbers.
....
You can use PaddedForm to align columns of numbers.
-----
Wenn man sich die Optionen von NumberForm und PaddedForm durchliest, die
weitgehend identisch sind, dann laesst sich die Leistung dieser Funktionen
_so ungefaehr_ mit den Displayfunktionen FIX (Fixpunkt-Zahlenformat), SCI
(wissenschaftliches Zahlenformat), ENG (ingenieurstechnisches Zahlenformat)
eines HP-Taschenrechners vergleichen.
Zu beachten
-----------
Bei einem HP Taschenrechner _formatiert man_ die Zahlendarstellung _im
Display_ zur besseren und uebersichtlicheren Darstellung.
Die _interne Zahlendarstellung_ aendert sich dabei _nicht_.
Kontrolle in MMa
----------------
listeNF = Map[ NumberForm[ #, { 5, 3} ] &, liste ]
{ 1., 1.2, 1.34, 1.234, 1.235}
listePF = Map[ PaddedForm[ #, { 5, 3} ] &, liste ]
{ 1.000, 1.200, 1.340, 1.234, 1.235"}
Und dann schauen wir uns an, was MMa daraus intern macht :
FullForm[ listeNF ]
List[NumberForm[1, List[5, 3]], NumberForm[1.2`, List[5, 3]],
NumberForm[1.34`, List[5, 3]], NumberForm[1.234`, List[5, 3]],
NumberForm[1.23456`, List[5, 3]]]
listePF = Map[ PaddedForm[ #, { 5, 3} ] &, liste ]
List[PaddedForm[1, List[5, 3]], PaddedForm[1.2`, List[5, 3]],
PaddedForm[1.34`, List[5, 3]], PaddedForm[1.234`, List[5, 3]],
PaddedForm[1.23456`, List[5, 3]]]
Dieses Ergebnis ueberraschte mich zuerst, aber es erklaert vermutlich
vieles.
Interpretation
--------------
Ich interpretiere es so,
dass MMa die Funktionen NumberForm[ .. ] und PaddedForm[ .. ]
_nur bei das Anzeige der Daten_
interpretiert.
Diese Funktionen _veraendern_ also die _interne Zahlendarstellung_ in MMa
_nicht_ !!
Meine Vermutung
---------------
Vermutlich werden also diese beiden Funktionen
NumberForm[ .. ] und PaddedForm[ .. ]
_nur im MMa-FrontEnd interpretiert_,
nicht aber im Ausgabepfad ueber die Funktion Export[ .. ] !
Mit der Export-Funktion leben
-----------------------------
Wenn das so richtig ist, dann kann man mit der Export-Funktion ganz gut
leben, wenn man sich an den folgenden Verarbeitungsfluss haelt :
- Daten einlesen
- Daten verarbeiten
- Daten formatieren und dabei _gleichzeitig_ ( !! ) in Strings wandeln
fuer Listen z.B. mit
dataOutputListe = Map[ ToString[ NumberForm[ #, {5,3} ] ] & ,
dataListe ]
oder
dataOutputListe = Map[ ToString[ PaddedForm[ #, {5,3} ] ] & ,
dataListe ],
fuer zweidimensionale Tabellen z.B. mit
dataOutputTable = Map[ ToString[ NumberForm[ #, {5,3} ] ] & ,
dataTable, {2} ]
oder
dataOutputTable = Map[ ToString[ PaddedForm[ #, {5,3} ] ] & ,
dataTable, {2} ],
je nach genauer Forderung
- Daten mit Export ausgeben ..
fuer Listen :
Export[ "dateiAusgabeListe.txt", dataOutputListe, "List" ]
oder Tabellen :
Export[ "dateiAusgabeTabelle.txt", dataOutputTable, "Table" ]
Minimalbeispiel
---------------
[ DMUG:ExportDemoGW ]
Korrekte Funktion
-----------------
Es funktioniert korrekt ( Tabellenausgabe mit _einer_ Stelle nach dem Komma
) :
tabelle = Table[ N[ 1 + i/10 + j /100 ], { i, 0, 4 }, { j, 0, 3} ]
tabellePFS = Map[ ToString[ PaddedForm[ #, { 5, 1} ] ] &, tabelle, {2}
]
Export[ "tabellePFS.txt", tabellePFS, "Table" ]
Denn es ergibt sich die Datei "tabellePFS.txt" mit dem folgenden Inhalt :
1.0 1.0 1.0 1.0
1.1 1.1 1.1 1.1
1.2 1.2 1.2 1.2
1.3 1.3 1.3 1.3
1.4 1.4 1.4 1.4
Inkorrekte Funktion
-------------------
_Nicht_ korrekt funktioniert
die Formatierung und Umwandlung in Strings in _zwei getrennten_
Schritten:
tabelle = Table[ N[ 1 + i/10 + j /100 ], { i, 0, 4 }, { j, 0, 3} ]
tabellePF = Map[ PaddedForm[ #, { 5, 1} ] &, tabelle ]
tabellePFS2 = Map[ ToString[ # ] &, tabellePF, {2} ]
Export[ "tabellePFS2.txt", tabellePFS2, "Table" ]
Denn dieser Berechnungspfad ergibt die Datei "tabellePFS2.txt" mit dem
folgenden Inhalt :
{1., 1.01, 1.02, 1.03}
{1.1, 1.11, 1.12, 1.13}
{1.2, 1.21, 1.22, 1.23}
{1.3, 1.31, 1.32, 1.33}
{1.4, 1.41, 1.42, 1.43}
Aufklaerung
-----------
Die Aufklaerung dieses Sachverhaltes liefern folgende Informationen :
Fuer die korrekt funktionierende Version
----------------------------------------
Head[ tabellePFS ]
List
Head[ tabellePFS[[1]] ]
List
Head[ tabellePFS[[1, 1]] ]
String
Fuer die _nicht_ korrekt funktionierende Version
-------------------------------------------------
Head[ tabellePFS2 ]
List
Head[ tabellePFS2[[1]] ]
PaddedForm
Head[ tabellePFS2[[1, 1]] ]
String
Meine Folgerungen
-----------------
Ich schliesse aus diesen Informationen zur Struktur der von Export
auszugebenden Tabellen,
dass Export
_nicht_ mit den _Formatierungsfunktionen_
NumberForm[ .. ] und PaddedForm[ .. ]
zurechtkommt.
Umgekehrt funktioniert Export
anscheinend ohne Probleme mit ( wohl auch geschachtelten ) Listen,
die Strings enthalten,
solange
_keine_ Formatierungsfunktionen enthalten sind.
Kommentare
----------
Diese Diskussion ist nach meinem aktuellen Verstaendnis richtig und sie war
hoffentlich auch verstaendlich.
Korrekturen und Kommentare ueberlasse ich gerne den erfahrenen
MMa-Anwendern der DMUG !
Ich freue mich immer, wenn ich noch etwas dazulernen kann.
Mit freundlichen Gruessen,
Gunter Woysch