Forum: PC-Programmierung CSV Datei: Zahlen Genauigkeit reduzieren 3.00000001 -> 3.00E+0


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Moritz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe CSV Dateien die eine große Dateigröße haben und deshalb schwer 
zu verarbeiten sind.

Die Daten sind im Format (beispielhaft)
1
X,Y,Z
2
1.00010001,  5.003, 1.000500001E-20
3
1.99999999, 10.001, 2.020100005E-21
4
3.02000001, 14.999, 3.000000011E-20
(Leerzeichen sind in der Datei nicht vorhanden, nur zur besseren 
Lesbarkeit)

Dh. die Zahlen haben einerseits sehr viele Nachkommastellen und sind zum 
Teil in E+XX Schreibweise.

Ich möchte jeztzt ein Skript schreiben, dass die Datei einliest, alle 
Zahlen auf eine vorgegebene Anzahl von Dezimalstellen rundet (bzw. 
abschneidet) und dann in eine neue Datei speichert.

Die Ausgabe sollte z.B. bei "3 Stellen Genaugigkeit" so aussehen:
1
X,Y,Z
2
1.00,  5.00,    1.00E-20
3
2.00,  1.00E+1, 2.00E-21
4
3.02,  1.50E+1, 3.00E-20
(ebenfalls Beispielhaft, ob alle Zahlen ein E+XX Format bekommen ist 
egal. Leerzeichen nur zur besseren Lesbarkeit eingefügt)

Danke schonmal
Moritz

PS: Skriptsprache ist egal, am liebsten etwas das unter Windows+Linux 
läuft (z.B. Python?)

von Achim (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Wo ist jetzt die Frage oder das Problem?

von Moritz (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Achim schrieb:
> Wo ist jetzt die Frage oder das Problem?

Ich suche ein Skript mit dem man die CSV Daten einlesen, Anzahl Stellen 
der Zahlen reduzieren und wieder abspeichern kann.

Danke!

von Tangens (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Regulärer Ausdruck + eine Programmiersprache deiner Wahl.

von Tasg (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gibt es in Tabellenkalkulationsprogrammen keine Funktion zum RUNDEN?! 
Probiers mal mit LibreOffice Calc, das ist umsonst.

von Markus F. (mfro)


Bewertung
0 lesenswert
nicht lesenswert
Dein Skript heißt LibreOffice.

Dort kann man Tabellen so als .csv exportieren, wie sie auf dem 
Bilschirm formatiert dargestellt sind.
Also einmal importieren, so formatieren, wie Du's haben willst und beim 
Wiederexportieren den Knopf "Zellinhalt wie angezeigt speichern" 
drücken.

Ob das in Excel auch geht, weiß ich nicht.

von Moritz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke schonmal für die Tipps.

Ich suche nach einer automatisierbaren Lösung, d.h. nicht Excel.

Im Idealfall kann ich das Skript per Kommandozeile starten, z.b.
1
convertSkript input.csv output.csv

Und es erstellt eine neue Datei mit reduzierter Genauigkeit der Daten.

Grüße
Moritz

von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Moritz schrieb:
> Ich suche nach einer automatisierbaren Lösung, d.h. nicht Excel.
>
> Im Idealfall kann ich das Skript per Kommandozeile starten, z.b.
> convertSkript input.csv output.csv
> Und es erstellt eine neue Datei mit reduzierter Genauigkeit der Daten.

Da musst DU wohl was tun ...

von Tasg (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Und wo ist jetzt das Problem? Jemand der ein bisschen Coden kann, kann 
sich das doch schnell in 15 Minuten (z.B. in Python) zusammenhacken.

von Tasg (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Foren wie diese sind eigentlich dafür gedacht, Leuten, die ein Problem 
mit irgendetwas haben, auf die Sprünge zu helfen oder Tipps zu geben. 
Das hier dient nicht dazu, für Lau Programme erstellt zu bekommen.

von Hilfreiche Person (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Hier eine Lösung mit Perl:
1
> cat csv
2
X,Y,Z
3
1.00010001,  5.003, 1.000500001E-20
4
1.99999999, 10.001, 2.020100005E-21
5
3.02000001, 14.999, 3.000000011E-20
6
7
> cat csv | perl -pe 's/([0-9]+\.[0-9]+([eE][ +-][0-9]+)?)/sprintf("%0.3g", $1)/ge'
8
X,Y,Z
9
1,  5, 1e-20
10
2, 10, 2.02e-21
11
3.02, 15, 3e-20

von W.A. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Moritz schrieb:
> Ich suche nach einer automatisierbaren Lösung, d.h. nicht Excel.

Makros funktionieren bei dir nicht? Einmal vorgeturnt und ...

von Vielleicht hilfreich (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Hier eine Lösung in C# (sollte in jede Sprache übertragen werden können)
1
static void Main(string[] args)
2
        {
3
            Regex regex = new Regex((@"-?\d +.?\d *)(E[+-]\d +) ?"));
4
            var temp = File.ReadAllText(args[0]);
5
            regex.Matches(temp).Cast<Match>().Select(match => match.Value).ToList().ForEach(match => {
6
                temp.Replace(match, Math.Round(Convert.ToDouble(match), Convert.ToInt32(args[2])).ToString());
7
            });
8
            File.WriteAllText(args[1], temp);
9
        }

Kann somit über die Kommandozeile mit <input.csv> <output.csv> <Stelle 
auf die gerundet werden soll> aufgerufen werden.

von Markus F. (mfro)


Bewertung
0 lesenswert
nicht lesenswert
Moritz schrieb:
> Ich suche nach einer automatisierbaren Lösung, d.h. nicht Excel.

Deswegen habe ich ja auch LibreOffice vorgeschlagen. Das läßt sich mit 
Python ganz prima skripten.

von Sebastian S. (amateur)


Bewertung
0 lesenswert
nicht lesenswert
Wozu das Ganze?

Was mich interessiert ist die Ausgabe und nicht das Rohformat!

Runde so viel Du willst bei der Ausgabe – von mir aus schneide alles was 
übersteht ab - aber lass die Rohdaten in Ruhe.

von Sebastian S. (amateur)


Bewertung
0 lesenswert
nicht lesenswert
Ich Vergaß (doppelt)!

Vor kurzem habe ich einen Artikel gelesen, nachdem 30% (man höre und 
staune) aller in (vom allem von Microsoft) Tabellen vorhandenen Daten, 
grobe Fehler enthalten. Vor allem durch nachträgliche "Verbesserungen". 
Oft beim Versionssprung automatisch durchgeführt!

Wenn Du Dich persönlich hier einreihen möchtest: Hau rein!

von Norbert (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Tasg schrieb:
> Probiers mal mit LibreOffice Calc, das ist umsonst.

Da muss ich widersprechen,
LibreOffice ist nicht umsonst, es ist kostenlos!

von Moritz (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Vielen Dank für die Hilfe, insbesondere mit dem regulären Ausdruck. 
Besten Dank.

PS: Ein Forum lebt vom geben und nehmen, deshalb freut es mich dass eine 
funktionsfähige Lösungen von Personen gepostet werden für die die 
Aufgabe leicht lösbar ist. Wenn die Person (ich) der damit Arbeit 
abgenommen wurde dann im Umkehrschluss in anderen Threads ebenfalls 
selbstlos Hilfe anbietet und anderen Zeit erspart haben alle profitiert. 
Insofern kann ich die Nörgler nicht verstehen und mich umsomehr bei den 
aktiven des Forums bedanken!

Grüße

Hilfreiche Person schrieb:
> Hier eine Lösung mit Perl:> cat csv
> X,Y,Z
> 1.00010001,  5.003, 1.000500001E-20
> 1.99999999, 10.001, 2.020100005E-21
> 3.02000001, 14.999, 3.000000011E-20
>
>> cat csv | perl -pe 's/([0-9]+\.[0-9]+([eE][ +-][0-9]+)?)/sprintf("%0.3g",
> $1)/ge'
> X,Y,Z
> 1,  5, 1e-20
> 2, 10, 2.02e-21
> 3.02, 15, 3e-20

Vielleicht hilfreich schrieb:
> Hier eine Lösung in C# (sollte in jede Sprache übertragen werden können)
> static void Main(string[] args)
>         {
>             Regex regex = new Regex((@"-?\d +.?\d *)(E[+-]\d +) ?"));
>             var temp = File.ReadAllText(args[0]);
>             regex.Matches(temp).Cast<Match>().Select(match =>
> match.Value).ToList().ForEach(match => {
>                 temp.Replace(match, Math.Round(Convert.ToDouble(match),
> Convert.ToInt32(args[2])).ToString());
>             });
>             File.WriteAllText(args[1], temp);
>         }
>
> Kann somit über die Kommandozeile mit <input.csv> <output.csv> <Stelle
> auf die gerundet werden soll> aufgerufen werden.

von Jim M. (turboj)


Bewertung
-1 lesenswert
nicht lesenswert
Moritz schrieb:
> ich habe CSV Dateien die eine große Dateigröße haben und deshalb schwer
> zu verarbeiten sind.

Ganz sicher? CSV wird normalerweise mit Interface-geschwindigkeit 
eingelesen.
D.h. Du würdest die Änderungen nur auf einem ganz lahmen NAS oder 
uraltem USB Stick merken, und das auch nur bei Dateien in GB Größe.

Ich sehe da überhaupt kein Einsparpotential: Die Konvertierung dauert 
viel länger als Du durch das ein ganz kleines bißchen schnellere 
Einlesen sparen wirst.

Drei signifikate Stellen sind übrigens nur ca. 10 Bit, gute ADCs gibt es 
mit 12, 14,..,24 Bit je nach Anwendung. Falls die Daten also nicht aus 
einem Arduino rausfallen wirfst Du hier Auflösung weg.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.