Frage zu einem Projekt

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
hubiat
User
Beiträge: 20
Registriert: Donnerstag 22. Juni 2006, 09:23

hallo,

ich bin neu auf dem gebiet python! :)
folgende fragen:

ich würde gerne den inhalt einer csv-datei auslesen
aus einer bestimmten spalte dann die einträge sortieren und zählen!
und je nach größe dann sortiert ausgeben in eine andere datei!

verständlich?!
könnte mir hier eventuell jemand behilflich sein?!

danke, jürgen
pr0stAta
User
Beiträge: 271
Registriert: Freitag 17. September 2004, 11:49
Wohnort: Bremen

Hallo hubiat, um aus CSV Dateien zu lesen brauchst du wohl
das CSV Modul.
Hier zu finden: http://www.python.org/doc/2.4/lib/module-csv.html

Dann solltest du einfach mal ein wenig per Suchfunktion gucken,
das Thema CSV wurde schon mehr als einmal hier angesprochen :)
BlackJack

hubiat hat geschrieben:ich würde gerne den inhalt einer csv-datei auslesen
aus einer bestimmten spalte dann die einträge sortieren und zählen!
und je nach größe dann sortiert ausgeben in eine andere datei!

verständlich?!
Nicht so ganz.

Zur Ein- und Ausgabe hast Du ja schon den Hinweis auf das `csv` Modul bekommen.

Aber die Beschreibung was Du mit den Daten anfangen willst, ist etwas schwammig. Willst Du nur die eine Spalte extrahieren und deren Werte sortieren oder sollen die ganzen Zeilen nach einer bestimmten Spalte sortiert werden?

Und was heisst zählen? Die Anzahl der Zeilen der "Tabelle" oder bestimmte Werte zählen?

Gib doch einfach mal ein paar Beispieldaten an und wie das Ergebnis aussehen soll.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

@hubiat: Such mal im Forum nach csv, wirst betimmt einige Threats finden wo auch die ein oder anderen Beispiele dabei sind...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
hubiat
User
Beiträge: 20
Registriert: Donnerstag 22. Juni 2006, 09:23

BlackJack hat geschrieben:
hubiat hat geschrieben:ich würde gerne den inhalt einer csv-datei auslesen
aus einer bestimmten spalte dann die einträge sortieren und zählen!
und je nach größe dann sortiert ausgeben in eine andere datei!

verständlich?!
Nicht so ganz.

Zur Ein- und Ausgabe hast Du ja schon den Hinweis auf das `csv` Modul bekommen.

Aber die Beschreibung was Du mit den Daten anfangen willst, ist etwas schwammig. Willst Du nur die eine Spalte extrahieren und deren Werte sortieren oder sollen die ganzen Zeilen nach einer bestimmten Spalte sortiert werden?

Und was heisst zählen? Die Anzahl der Zeilen der "Tabelle" oder bestimmte Werte zählen?

Gib doch einfach mal ein paar Beispieldaten an und wie das Ergebnis aussehen soll.
hmm...das mit dem schwammig stimmt! :)
also meine CSV Datei sieht nun zum beispiel folgendermaßen aus:

Name,Level,Type,Numerical Type,Size,Type Kind,Instance Kind,EP-Nr.,Offset,Type id,Flags
NewTypeInstance,0,Type,0,40,1,,184295,0,3,0
ENO,1,BOOL,9,1,128,2,184295,0,,0
UDINT,1,UDINT,16,4,128,8,184295,4,,0
UDINT1,1,UDINT,16,4,128,8,184295,8,,0
INT,1,INT,11,2,128,8,184295,12,,0


Hier möchte ich nun nur den Inhalt der Spalte Type filtern, diese dann sortieren!
Dem nicht genug, sollte dann ausgegeben werden zum beispiel:
1 x ENO
2 x UDINT
1 x INT

also eine Liste mit der Anzahl der Typen!
Und diese Liste sollte dann sortiert ausgegeben werden!

und ich steh derzeit einfach voll an, wie ich das am besten lösen könnte!

Danke schon mal im Vorhinein, für Eure Bemühungen!!!
BlackJack

Deine Beispiel-Liste ist aber weder nach der Anzahl noch nach Typname sortiert!? Na egal, man könnte das z.B. so lösen:

Code: Alles auswählen

from csv import DictReader

data_file = open('test.csv')

rows = DictReader(data_file)

histogram = dict()
for row in rows:
    key = row['Type']
    histogram[key] = histogram.get(key, 0) + 1

data_file.close()

for key in sorted(histogram.iterkeys()):
    print '%3d x %s' % (histogram[key], key)
hubiat
User
Beiträge: 20
Registriert: Donnerstag 22. Juni 2006, 09:23

BlackJack hat geschrieben:Deine Beispiel-Liste ist aber weder nach der Anzahl noch nach Typname sortiert!? Na egal, man könnte das z.B. so lösen:

Code: Alles auswählen

from csv import DictReader

data_file = open('test.csv')

rows = DictReader(data_file)

histogram = dict()
for row in rows:
    key = row['Type']
    histogram[key] = histogram.get(key, 0) + 1

data_file.close()

for key in sorted(histogram.iterkeys()):
    print '%3d x %s' % (histogram[key], key)

ja, stimmt! hast recht! hab ich in der hitze des gefechts komplett verhaut! *fg*
hey, danke...das schaut ja schon mal nicht so schlecht aus!
dafür hätt ich noch ne gaaanze weile gebraucht!

jetzt krieg ich zum beispiel folgende ausgabe:

4 x ADD_INT_N3
4 x ADD_UDINT_N3
5 x BOOL
8 x INT
4 x REAL
1 x Type
8 x UDINT

Kann ich die irgendwie dann auch in aufsteigender größe sortieren?!

Was ich noch Frage wollte!
Mein Hauptproblem ist einfach, dass ich viele Funktionen gar nicht kenne, bzw. nicht weiß, was welche macht?!
Gibts hierfür eigentlich auch irgendetwas annehmbares in Deutsch?!
Das wär eine feine Sache!

Danke im Vorhinein und lg, Jürgen
BlackJack

Jetzt sind sie ja in aufsteigender Reihenfolge nach dem Typnamen sortiert. ;-)

Wenn Du nach Anzahl sortieren möchtest dann müsste die ``for``-Schleife z.B. so aussehen:

Code: Alles auswählen

for item in sorted((count, typename)
                   for (typename, count) in histogram.iteritems()):
    print '%3d x %s' % item
hubiat
User
Beiträge: 20
Registriert: Donnerstag 22. Juni 2006, 09:23

BlackJack hat geschrieben:Jetzt sind sie ja in aufsteigender Reihenfolge nach dem Typnamen sortiert. ;-)

Wenn Du nach Anzahl sortieren möchtest dann müsste die ``for``-Schleife z.B. so aussehen:

Code: Alles auswählen

for item in sorted((count, typename)
                   for (typename, count) in histogram.iteritems()):
    print '%3d x %s' % item
aja...danke! du bist echt ein meister des python faches!
nun hab ich als letztes problem, folgendes:

Größe jedes einzelnen Typen (in Byte) (Spalte 6(Size) ausgeben
Größe des Gesamtspeicherverbrauches (Byte Gesamt) ausgeben

Also hier ein Beispiel:

BOOL hat zum Beispiel die Größe 128 Byte

Ausgabe ist derzeit => 5 x BOOL
Dann sollte folgende Ausgabe ca. definiert werden:

5 x BOOL (128 Byte) = 640 Byte (Gesamtspeicherverbrauch)

Damit weiß ich dann, wie groß der Speicherverbrauch für einen Datentypen BOOL ist und wie groß der Gesamtspeicherverbrauch, indem einfach die Anzahl der Datentypen multipliziert mit der Größe für einen wird!

Wie löst man das am besten?!
Anhand deiner Codes, hab ich schon eine Menge dazugelernt, nur darauf einmal zu kommen, ist für einen Newbie wie für mich, nicht so leicht!
aber da gibt es ja ein sprichwort: es ist noch kein meister vom himmel gefallen! ich hau mich jedenfalls voll rein und hoffe, dass ich auch einmal hier im forum so supporten kann wie du! :)

DANKE!!!! schon mal im vorraus!!!
bist mir echt eine große hilfe!!!!
BlackJack

hubiat hat geschrieben:Ausgabe ist derzeit => 5 x BOOL
Dann sollte folgende Ausgabe ca. definiert werden:

5 x BOOL (128 Byte) = 640 Byte (Gesamtspeicherverbrauch)

Damit weiß ich dann, wie groß der Speicherverbrauch für einen Datentypen BOOL ist und wie groß der Gesamtspeicherverbrauch, indem einfach die Anzahl der Datentypen multipliziert mit der Größe für einen wird!
Ich habs umgekehrt gemacht; erst die Grösse immer aufaddiert und dann bei der Ausgabe die Gesamtgrösse durch die Anzahl geteilt:

Code: Alles auswählen

from csv import DictReader

data_file = open('test.csv')

rows = DictReader(data_file)

histogram = dict()
for row in rows:
    typename = row['Type']
    size = int(row['Size'])
    count, total_size = histogram.get(typename, (0, 0))
    histogram[typename] = (count + 1, total_size + size)

data_file.close()

for count, typename, size in sorted((count, typename, size)
                                    for typename, (count, size)
                                    in histogram.iteritems()):
    print '%3d x %s (%d Byte)= %d Byte gesamt' % (count,
                                                  typename,
                                                  size / count,
                                                  size)
hubiat
User
Beiträge: 20
Registriert: Donnerstag 22. Juni 2006, 09:23

BlackJack hat geschrieben:
hubiat hat geschrieben:Ausgabe ist derzeit => 5 x BOOL
Dann sollte folgende Ausgabe ca. definiert werden:

5 x BOOL (128 Byte) = 640 Byte (Gesamtspeicherverbrauch)

Damit weiß ich dann, wie groß der Speicherverbrauch für einen Datentypen BOOL ist und wie groß der Gesamtspeicherverbrauch, indem einfach die Anzahl der Datentypen multipliziert mit der Größe für einen wird!
Ich habs umgekehrt gemacht; erst die Grösse immer aufaddiert und dann bei der Ausgabe die Gesamtgrösse durch die Anzahl geteilt:

Code: Alles auswählen

from csv import DictReader

data_file = open('test.csv')

rows = DictReader(data_file)

histogram = dict()
for row in rows:
    typename = row['Type']
    size = int(row['Size'])
    count, total_size = histogram.get(typename, (0, 0))
    histogram[typename] = (count + 1, total_size + size)

data_file.close()

for count, typename, size in sorted((count, typename, size)
                                    for typename, (count, size)
                                    in histogram.iteritems()):
    print '%3d x %s (%d Byte)= %d Byte gesamt' % (count,
                                                  typename,
                                                  size / count,
                                                  size)

*wow*
das geht alles so einfach und schnell bei dir!
könntest mir eventuell die zeilen bissi erklären?!
ginge das auch?!
checks eh einigermaßen, aber für den vollständigen "aha - effekt" reicht´s für mich leider "noch" nicht!

DANKE und lg, jürgen
BlackJack

hubiat hat geschrieben:das geht alles so einfach und schnell bei dir!
könntest mir eventuell die zeilen bissi erklären?!
Erstmal nochmal das Progrämmchen mit ein paar Kommentaren und einer ``print`` Anweisung um zu sehen was passiert.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from csv import DictReader
from pprint import pprint   # Für "schöne" Ausgaben von eingebauten Datentypen.

data_file = open('test.csv')

# 
# Ein `DictReader` Objekt ist ein Iterator, d.h. es gibt eine `next()`
# Methode, welche die jeweils nächste Zeile der CSV Datei zurückgibt.
# Und zwar als Dictionary mit den Spaltennamen als Schlüsseln.
# 
rows = DictReader(data_file)
# 
# Das Dictionary `histogram` wird eine Abbildung von Typnamen auf ein
# Tupel mit zwei Elementen aufnehmen, die Anzahl wie oft der Typ schon
# in der Eingabe vorkam und die Gesamtgrösse in Bytes.
# 
histogram = dict()
# 
# Iteratoren kann man in ``for``-Schleifen verwenden.  `row` bekommt in
# jedem Schleifendurchlauf die nächste Zeile aus der CSV Datei zugewiesen.
# (Vorsicht: das Dictionary wird dabei wiederverwendet!)
# 
for row in rows:
    # 
    # Nun werden aus dem Zeilen-Dictionary die beiden Werte geholt, die
    # uns interessieren.  Da mit `size` gerechnet werden soll, muss die
    # Zeichenkette mit `int()` in eine ganze Zahl umgewandelt werden.
    # 
    typename = row['Type']
    size = int(row['Size'])
    # 
    # Aus dem `histogram` werden bisherige Anzahl und Grösse zu `typename`
    # geholt.  Wenn es `typename` noch nicht gibt, dann wird (0, 0) von
    # `get()` zurückgegeben.
    # 
    count, total_size = histogram.get(typename, (0, 0))
    # 
    # Zur Anzahl wird 1 addiert, und zur bisherigen Gesamtgrösse die
    # Grössenangabe aus der aktuellen Zeile in der CSV Datei und das ganze
    # wird wieder unter `typename` in das Dictionary eingetragen.
    # 
    histogram[typename] = (count + 1, total_size + size)
# 
# Mal schauen wie das Dictionary jetzt aussieht.
# 
pprint(histogram)

data_file.close()

# 
# Hier werden jetzt die Daten aus dem `histogram` in Tupel mit der
# entsprechenden Reihenfolge gepackt wie sie zum sortieren benötigt
# wird, also erst die Anzahl und dann der Typname und zuletzt die
# Gesamtgrösse und dann wird mit `sorted() `sotiert.
# 
# Und dann wird jedes Tupel ausgegeben.
# 
for count, typename, size in sorted((count, typename, size)
                                    for typename, (count, size)
                                    in histogram.iteritems()):
    print '%3d x %s (%d Byte) = %d Byte gesamt' % (count,
                                                   typename,
                                                   size / count,
                                                   size)
Die Ausgaben mit Deinen Testdaten weiter oben im Thread:

Code: Alles auswählen

{'INT': (1, 2), 'BOOL': (1, 1), 'UDINT': (2, 8), 'Type': (1, 40)}
  1 x BOOL (1 Byte) = 1 Byte gesamt
  1 x INT (2 Byte) = 2 Byte gesamt
  1 x Type (40 Byte) = 40 Byte gesamt
  2 x UDINT (4 Byte) = 8 Byte gesamt
Das schöne an Python ist der Interpreter mit dem man vieles "live" ausprobieren kann. Zum Beispiel wie so ein `DictReader` funktioniert:

Code: Alles auswählen

In [16]: data_file = open('test.csv')

In [17]: rows = csv.DictReader(data_file)

In [18]: rows.next()
Out[18]:
{'EP-Nr.': '184295',
 'Flags': '0',
 'Instance Kind': '',
 'Level': '0',
 'Name': 'NewTypeInstance',
 'Numerical Type': '0',
 'Offset': '0',
 'Size': '40',
 'Type': 'Type',
 'Type Kind': '1',
 'Type id': '3'}

In [19]: rows.next()
Out[19]:
{'EP-Nr.': '184295',
 'Flags': '0',
 'Instance Kind': '2',
 'Level': '1',
 'Name': 'ENO',
 'Numerical Type': '9',
 'Offset': '0',
 'Size': '1',
 'Type': 'BOOL',
 'Type Kind': '128',
 'Type id': ''}
Ansonsten kannst Du auch ``print`` Anweisungen im Programm verteilen um zu sehen was passiert.
hubiat
User
Beiträge: 20
Registriert: Donnerstag 22. Juni 2006, 09:23

SUPER! Danke!
jetzt steh ich vor weiteren fragen?!

1) ich hab nun diese ausgabe am IDE!
wie krieg dieses ergebnis in eine txt datei zum beispiel?!

2) wie kann ein input file (test1.csv) und output file (statistik.txt) über die shell realisieren?! d.h. ich schreib die Dateien nicht fix in den source code hinein, sondern geb diese dann einfach in der shell ein

zum beispiel so:
python fileanalyse.py test1.csv >statistik.txt

hat hierfür jemand eine idee?!?!

wär super!

ps: muss sagen, ich hab noch nie so eine super community wie die hier gesehen! *respect*
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Die Parameter, die du an dein Programm uebergibst, stehen in sys.argv. Du kannst zum Beispiel Ein- und Ausgabedatei uebergeben. Wenn die Paramter komplizierter werden, schau dir mal das Modul optparse an.

Und wenn du den Output via Ausgabeumlenkung ">" in der Shell in eine Datei lenken willst, muss dein Programm seine Ausgabe einfach auf den Bildschirm schreiben (print oder sys.stdout.write).
hubiat
User
Beiträge: 20
Registriert: Donnerstag 22. Juni 2006, 09:23

Rebecca hat geschrieben:Die Parameter, die du an dein Programm uebergibst, stehen in sys.argv. Du kannst zum Beispiel Ein- und Ausgabedatei uebergeben. Wenn die Paramter komplizierter werden, schau dir mal das Modul optparse an.

Und wenn du den Output via Ausgabeumlenkung ">" in der Shell in eine Datei lenken willst, muss dein Programm seine Ausgabe einfach auf den Bildschirm schreiben (print oder sys.stdout.write).
wie ist das nun gemeint?!
wie kann ich da in sys.argv nachsehen?!
was muss ich da genau machen?!

danke im vorhinein für eure hilfe!!!
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

sys.argv ist einfach eine Liste. Das erste Element (sys.argv[0]) ist der Programmname, die restlichen sind die Parameter, die deinem Programm uebergeben wurden. Folgendes Programm gibt alle seine Parameter aus:

Code: Alles auswählen

import sys;
for arg in sys.argv:
    print arg
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

hubiat hat geschrieben:wie kann ich da in sys.argv nachsehen?!
Hi hubiat!

http://docs.python.org/lib/module-sys.html#l2h-329

Code: Alles auswählen

import sys
print sys.argv
print sys.argv[0]
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
hubiat
User
Beiträge: 20
Registriert: Donnerstag 22. Juni 2006, 09:23

ich glaub ich bin einfach zu blöd dafür! :--(

wie find ich mit diesen unterlagen genau heraus, wie ich ein file zum beispiel in der command line angebe?!?!

ich würde gern folgendes machen:

fileanalyse.py Test.csv >fileanalyse.txt

damit mein ich das python programm aufrufen, das test.csv file analysieren und das ergebnis nach fileanalyse.txt umleiten! :)

ich bin einfach zu blöd glaub ich, wie ich das am besten angehe!
*arrrgh* könnte mir hier jemand eventuell einen tipp geben, wie ich das am besten meistere?! damit mein ichaber uach das suchen danach im forum!
pr0stAta
User
Beiträge: 271
Registriert: Freitag 17. September 2004, 11:49
Wohnort: Bremen

Ich gebe zu ich habe mir den Teil davor nun nicht
durchgelesen aber ich würde dir schonmal empfehlen,
den Aufruf ohne ">" zu machen. Also eher so:

fileanalyse.py Test.csv fileanalyse.txt
In der Datei fileanalyse.py kannst du mit sys.argv[1] und sys.argv[2]
auf die 2 Parameter zugreifen, die du übergeben hast.

Code: Alles auswählen

import sys

print sys.argv[1]
print sys.argv[2]
*wie vorher auch schon erklärt*

Ergibt:

Code: Alles auswählen

C:\Dokumente und Einstellungen\lokal\Desktop>fileanalyse.py Test.csv fileanalyse.txt
Test.csv
fileanalyse.txt
Antworten