Tabelle bearbeiten

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.
Antworten
PyN
User
Beiträge: 12
Registriert: Donnerstag 12. Dezember 2019, 16:09

Hallo zusammen

wäre jemand so lieb zu Helfen / einen Denkanstoss für folgendes Problem geben:

Ausgangstabelle besteht aus drei Spalten mit n - Zeilen.
Spalte 1=Datum (gleiches Datum kann öfters vorkommen)
Spalte 2: Identifier (gleicher Identifier kann häufiger vorkommen)
Spalte 3: zugehöriger Wert

Zieltabelle:
N Zeilen mit Inhalt zugehöriger Wert bei Match sonst 0
N Spalten mit erster Spalte Datum und dann Identifier als Überschrift
Bei der Zieltabelle soll jedes Datum nur einmal vorkommen.

Denkt ihr das ist möglich ?
Ich hoffe es war verständlich erklärt.
Schonmal besten Danke für jede Anregung :)
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich verstehe das nicht. Was ist der "zugehoeriger match"? Und was sind die N? Und was sollen N Spalten sein, die dann wiederum eine Spalte haben? Kannst du mal ein Beispiel aus Daten und dann dazugehoerigem Ergebnis machen?
PyN
User
Beiträge: 12
Registriert: Donnerstag 12. Dezember 2019, 16:09

na klar.

Meine Ausgangstabelle:
Datum | Identifier | Wert
20.11 | ID 1 | 2,1
19.11 | ID1 | 1,3
20.11 | ID2 | 0,5

Zieltabelle:

Datum | ID 1 | ID 2
20.11 | 2,1 | 0,5
19.11 | 1,3 | -

Wobei die Werte nicht aggregiert werden dürfen...

Danke schonmal für deine schnelle Antwort.
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du willst also fuer jedes Datum aus jeder ID eine Spalte machen, und deren Werte dann eintragen. Was passiert, wenn am gleichen Tag mehrfach die gleiche ID vorkommt? Sollen die Werte dann verbunden werden?
PyN
User
Beiträge: 12
Registriert: Donnerstag 12. Dezember 2019, 16:09

am gleichen Tag kann eine ID nur einmal vorkommen

für jedes Datum soll es eine Zeile geben und für jede ID eine Spalte
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na dann: ueber die mit einem Reader aus dem csv-Modul eingelesenen Zeilen iterieren, und in einem Woerterbuch (dict) fuer jedes Datum wieder ein Woerterbuch anlegen. Kann man elegant zB mit collections.defaultdict machen. Dann den Wert fuer aktuelles Datum und ID eintragen. Gleichzeitig eine Menge (set) von allen IDs mit der aktuellen ID fuettern. Damit hat man dann alles eingelesen.

Zum schreiben ueber die Schluessel/Werte des Woerterbuches iterieren. Schluessel ist ja ein Datum, das als ersten Wert in eine neue Liste eintragen. Dann ueber die Menge der IDs iterieren, und wenn dafuer ein Wert im aktuellen Wert ist (das ist ja wiederum das Woerterbuch ID->Werte), dann die Werte an die Liste anhaengen. Sonst einen leeren Wert anhaengen, damit die Spalten passen.

Danach die Liste fuer eine Zeile mit einem csv-Writer wegschreiben.
PyN
User
Beiträge: 12
Registriert: Donnerstag 12. Dezember 2019, 16:09

vielen Dank !

Ich werde mich gleich mal ausprobieren
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Hier mal die zentrale Logik, ohne Ein- und Ausgabe mittels csv:

Code: Alles auswählen

data = [
    ['20.11', 'ID1', 2.1],
    ['19.11', 'ID1', 1.3],
    ['20.11', 'ID2', 0.5],
]

transposed = list(zip(*data))
ids = sorted(set(transposed[1]))
dates = sorted(set(transposed[0]))

tmp = {}
for date, id, value in data:
    tmp[date, id] = value

print('Datum', end = ' | ')
for id in ids:
    print(id, end=' | ')
print()

for date in dates:
    print(date, end=' | ')
    for id in ids:
        print(tmp.get((date, id), ' - '), end=' | ')
    print()
Ergebnis:

Code: Alles auswählen

Datum | ID1 | ID2 | 
19.11 | 1.3 |  -  | 
20.11 | 2.1 | 0.5 | 
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@pillmuncher: das mit den zwei Wörterbüchern ist deutlich einfacher, weil man nur einmal über die Daten iterieren muß.

Code: Alles auswählen

data = [
    ['20.11', 'ID1', 2.1],
    ['19.11', 'ID1', 1.3],
    ['20.11', 'ID2', 0.5],
]

ids = set()
matrix = defaultdict(dict)
for date, id, value in data:
    ids.add(id)
    matrix[date][id] = value
PyN
User
Beiträge: 12
Registriert: Donnerstag 12. Dezember 2019, 16:09

Danke für eure Hilfe. Habe es leider aber trotzdem noch nicht ans Ziel geschafft....


Urpsrungsformat ist ein Dataframe mit Spalten: date, ID, Wert
Da ich mich in Python noch kaum auskenne habe ich den vorherigen Code probiert anzupassen:

Liste=df.values.tolist()

transposed = list(zip(*Liste))
ids = sorted(set(transposed[1]))
dates = sorted(set(transposed[0]))

tmp = {}
for date, id, value in Liste:
tmp[date, id] = value

for date in dates:
for id in ids:
(tmp.get((date, id)))

x=pd.DataFrame.from_dict(tmp, orient="index")

Zielformat sollte wieder eine CSV Datei werden


wäre echt lieb, wenn ihr mir nochmal helfen könntet :)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@PyN: das hättest Du auch gleich verraten können, dass Du pandas benutzen willst.

Dann mußt Du erst ein passendes Dataframe erzeugen, das Du dann füllen kannst:

Code: Alles auswählen

data = [
    ['20.11', 'ID1', 2.1],
    ['19.11', 'ID1', 1.3],
    ['20.11', 'ID2', 0.5],
]
df = pandas.DataFrame(data, columns=['date','id','value'])
matrix = pandas.DataFrame(index=df['date'].unique(), columns=df['id'].unique())
PyN
User
Beiträge: 12
Registriert: Donnerstag 12. Dezember 2019, 16:09

Wollen schon nur können noch nicht :D Habe heute mit pandas angefangen...

df = pandas.DataFrame(data, columns=['date','id','value'])
matrix = pandas.DataFrame(index=df['date'].unique(), columns=df['id'].unique())

matrix.to_csv(r"C:\...xy.csv")

Damit steht das "Grundgerüst" perfekt!

Kannst du mir noch sagen, wie ich die Werte einfügen kann in die Zeilen? Im Moment sind noch alle Zeilen bis auf die Beschriftungen leer...

Bin dir echt richtig dankbar.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Am einfachsten mit einer Schleife füllen.

Code: Alles auswählen

for row in df.itertuples():
    matrix.loc[row.date, row.id] = row.value
Gibt bestimmt in Pandas noch was besseres, aber finde gerade nichts.
Antworten