Trädvy Permalänk
Medlem
Registrerad
Jun 2012

Hämta specifika datum python

Har hämtat en lista på datum från en csv fil. Om jag nu vill kunna få fram de rader där datumen ligger mellan ett start och slutdatum hur gör jag detta på bästa sätt? På dessa datum som jag hämtar så kommer jag behöva data som ligger på samma rad.

startdatum;slutdatum;data1;data2;data3 2014-01-01;2014-04-14;0;0;0

Ungefär så ser min csv fil. Jag hade tänkte mig något i stil med att för varje rad lägga denna data i listor och på så vis så vet jag att myLists med index[0] kommer va data från samma rad. Men nu vill jag hämta ut de rader med specifika datum som ligger mellan ett start och slutdatum.

whatdate = input('startdate?:') idx = myStartdate.index(whatdate) print idx

På detta sätt så skulle jag kunna veta vart i min sorterade lista jag skulle kunna börja, men fungerar inte om datument jag skrivit in inte finns med i listan. Så jag skulle behöva ett sätt hämta de rader som ligger inom ett datum intervall. Finns det något bra sätt att kolla detta i python.

CPU: Intel core i5 3450 | GPU: Asus Radeon HD 7870 | PSU: Corsair GS 600W | Moderkort: MSI b75a-g43 | HDD WD blue 500 GB | RAM: Crucial ballistiX 2x4gb DDR3 1600MHz | Ljudkort: Asus Xonar DG |

Trädvy Permalänk
Medlem
Registrerad
Jan 2014
Skrivet av turbogeten:

startdatum;slutdatum;data1;data2;data3 2014-01-01;2014-04-14;0;0;0

Om det huvudsakligen är intressant att filtrera på datum hade jag nog gjort ungefär så här (med reservation för fel; jag har ingen pythontolk att testa på):

  1. Låt python tolka CSV-filen.

  2. Omvandla datumsträngar till ett 'date'-objekt för att lättare kunna göra jämförelser med andra datum.

import csv import datetime # Importera & omvandla CSV-filen till en lista med python-'dicts'. Sno nycklar till 'dict'en från CSV-filens första rad. # Vi kommer alltså att få ut ungefär # { # 'data2': '0', # 'data1': '0', # 'data3': '0', # 'slutdatum': '2014-04-14', # 'startdatum': '2014-01-01' # } date_entries = [] for entry in csv.DictReader(open('filnamn.csv', 'r'), delimiter=';', ): date_entries.append(entry) # Gå igenom listan och ersätt datumsträngarna med datumobjekt. for entry in date_entries: start_year, start_month, start_day = entry['startdatum'].split('-') entry.['startdatum'] = datetime.date(year=int(startyear), month=int(startmonth), day=int(startday)) stop_year, stop_month, stop_day = entry['slutdatum'].split('-') entry.['slutdatum'] = datetime.date(year=int(stopyear), month=int(stopmonth), day=int(stopday))

Så! Nu blir det enklare att göra jämförelser och filtrera.

Citat:

Men nu vill jag hämta ut de rader med specifika datum som ligger mellan ett start och slutdatum.

OK. Nedanstående ger dig alla poster med ett datumintervall som "får plats" mellan ett start- och slutdatum, inte sådana som endast delvis överlappar angivet intervall:

startdate = datetime.date(year='2014', month='01', day='01') stopdate = datetime.date(year='2015', month='01', day='01') for entry in date_entries: if entry['startdatum'] > startdate and entry['slutdatum'] < stopdate: print entry # Eller vad du nu vill göra.

Trädvy Permalänk
Medlem
Registrerad
Jun 2012

@Hieronymus Bosch:
tack ser bra, ska testa

CPU: Intel core i5 3450 | GPU: Asus Radeon HD 7870 | PSU: Corsair GS 600W | Moderkort: MSI b75a-g43 | HDD WD blue 500 GB | RAM: Crucial ballistiX 2x4gb DDR3 1600MHz | Ljudkort: Asus Xonar DG |

Trädvy Permalänk
Medlem
Registrerad
Jun 2012

@Hieronymus Bosch:
min csv fil innehåller fler rader än de jag skrev ut som exempel. Men i dictionary är det inte så att det bara kan finnas ett värde till varje nyckel? Eller finns det något du tänkte på i ditt exempel som kommer runt det?

CPU: Intel core i5 3450 | GPU: Asus Radeon HD 7870 | PSU: Corsair GS 600W | Moderkort: MSI b75a-g43 | HDD WD blue 500 GB | RAM: Crucial ballistiX 2x4gb DDR3 1600MHz | Ljudkort: Asus Xonar DG |

Trädvy Permalänk
Medlem
Registrerad
Jan 2014
Skrivet av turbogeten:

Men i dictionary är det inte så att det bara kan finnas ett värde till varje nyckel?

Så är det!
Det skapas en lista av dictionaries, så varje rad lagras i en egen dict.
Däremot kommer det att gå åt helskotta om flera kolumner har samma rubrik.
Om de intressanta kolumnerna kommer först går det att jobba sig runt problemet med dubbletter bland kolumnnamnen genom att använda fieldnames-argumentet till DictReader:

csv.DictReader( open('filnamn.csv', 'r'), delimiter=';', fieldnames=['startdatum', 'slutdatum'] )

På så vis kommer de två första fälten i varje rad att få nycklar från listan i fieldnames. Resterande fält hamnar som en lista under nyckeln None. Like so:

2014-01-01;2014-04-14;1;2;3

blir

{ 'startdatum': '2014-01-01', 'slutdatum': '2014-04-14', None: ['1', '2', '3'] }

Men säg den lycka som varar! Genom att fieldnames är satt så kommer DictReader inte att tro att första raden är fältnamn utan tolkar dessa som data. För att hoppa över den första raden i filen kan man göra något i stil med

date_entries.pop(0)

efter att filen lästs in.

Trädvy Permalänk
Medlem
Registrerad
Jun 2012
Skrivet av Hieronymus Bosch:

# Gå igenom listan och ersätt datumsträngarna med datumobjekt.
for entry in date_entries:
start_year, start_month, start_day = entry['startdatum'].split('-')
entry.['startdatum'] = datetime.date(year=int(startyear), month=int(startmonth), day=int(startday))
stop_year, stop_month, stop_day = entry['slutdatum'].split('-')
entry.['slutdatum'] = datetime.date(year=int(stopyear), month=int(stopmonth), day=int(stopday))
[/code]

Får inte denna del att fungera, är inte säker om jag fått listan med dictionares att fungera heller som tänkt för de blir väldigt mycket dictionaries som skrivs ut när jag testat printa den.

entry.['datestart'] = datetime.date(year=int(startyear), month=int(startmonth), day=int(startday)) ^ SyntaxError: invalid syntax

CPU: Intel core i5 3450 | GPU: Asus Radeon HD 7870 | PSU: Corsair GS 600W | Moderkort: MSI b75a-g43 | HDD WD blue 500 GB | RAM: Crucial ballistiX 2x4gb DDR3 1600MHz | Ljudkort: Asus Xonar DG |

Trädvy Permalänk
Medlem
Registrerad
Jan 2014
Skrivet av turbogeten:

Får inte denna del att fungera, är inte säker om jag fått listan med dictionares att fungera heller som tänkt för de blir väldigt mycket dictionaries som skrivs ut när jag testat printa den.

Ja, det borde bli en väldigt oläslig störtflod av citattecken, krullparenteser och annat. Om du kör programmet med 'python -i programmet.py' så kommer programmet att köras och därefter lämna dig i pythonprompten, där du i lugn och ro kan kolla igenom vad variabler innehåller. Prova t ex 'print(entry)' eller 'len(date_entries)'.

Skrivet av Python:

SyntaxError: invalid syntax

Där ser man. Jag har tydligen inte kunnat bestämma mig för om varje rad ska lagras som ett objekt (och startdatumet som ett attribut, entry.startdate) eller som en dict (entry['startdate']). Ta bort punkterna mellan 'entry' och hakparentesen så funkar det lite bättre. Dessutom har jag inte heller kunnat bestämma mig för vad variablerna ska heta: 'start_year' och 'startyear' huller om buller, t ex.

for entry in date_entries: start_year, start_month, start_day = entry['startdatum'].split('-') entry['startdatum'] = datetime.date(year=int(startyear), month=int(startmonth), day=int(startday)) stop_year, stop_month, stop_day = entry['slutdatum'].split('-') entry['slutdatum'] = datetime.date(year=int(stopyear), month=int(stopmonth), day=int(stopday))

Trädvy Permalänk
Medlem
Registrerad
Jun 2012

@Hieronymus Bosch:
Tack för hjälpen fick det att fungera nu, ska bara skriva ut från dicten nu.

CPU: Intel core i5 3450 | GPU: Asus Radeon HD 7870 | PSU: Corsair GS 600W | Moderkort: MSI b75a-g43 | HDD WD blue 500 GB | RAM: Crucial ballistiX 2x4gb DDR3 1600MHz | Ljudkort: Asus Xonar DG |

Trädvy Permalänk
Medlem
Registrerad
Jun 2012

@Hieronymus Bosch:
Lyckats lösa de, var klumpig på min uträkning med datan som jag fått ut. Tack för hjälpen sen tidigare igen

CPU: Intel core i5 3450 | GPU: Asus Radeon HD 7870 | PSU: Corsair GS 600W | Moderkort: MSI b75a-g43 | HDD WD blue 500 GB | RAM: Crucial ballistiX 2x4gb DDR3 1600MHz | Ljudkort: Asus Xonar DG |