Hoe de datum/datum/tijd-kolommen automatisch te detecteren en hun gegevenstype in te stellen bij het lezen van een CSV-bestand in Panda's

Bronknooppunt: 1106147

Hoe de datum/datum/tijd-kolommen automatisch te detecteren en hun gegevenstype in te stellen bij het lezen van een CSV-bestand in Panda's

Wanneer read_csv( ) bijvoorbeeld "2021-03-04" en "2021-03-04 21:37:01.123" leest als louter "object"-datatypes, kunt u ze vaak eenvoudig allemaal tegelijk automatisch converteren naar echte datetime-datatypes.


By David B. Rosen (PhD), Lead Data Scientist voor geautomatiseerde kredietgoedkeuring bij IBM Global Financing



Stel dat ik een CSV-gegevensbestand heb dat ik wil inlezen in een Pandas-dataframe, en sommige kolommen zijn datums of datum-tijden, maar ik wil niet de moeite nemen om de namen van deze kolommen van tevoren te identificeren/specificeren. In plaats daarvan zou ik automatisch de datatypes willen verkrijgen die worden getoond in de df.info() uitvoer afgebeeld bovenstaande, waar de juiste kolommen zijn geweest webmaster. gegeven een datum/tijd-gegevenstype (groene kaders). Ga als volgt te werk om dat te bereiken:

from dt_auto import read_csv
df=read_csv('myfile.csv')

Merk op dat ik dat deed niet roep pd.read_csv (de Pandas-versie van read_csv) hierboven direct aan. Mijn functie dt_auto.read_csv (zie de code hieronder) heeft pd.read_csv() zelf aangeroepen en vervolgens automatisch het datatype van de twee gedetecteerde datetime-kolommen gedetecteerd en geconverteerd. (De inhoud van deze df wordt hieronder weergegeven.)

Als ik de reguliere Panda's pd.read_csv() had gebruikt, zou ik standaard alleen generieke objectdatatypes hebben verkregen, zoals hieronder (rode kaders):

from pandas import read_csv
df=read_csv('myfile.csv')
df.info()



Merk op dat het enige verschil met de originele code zit in de importverklaring, waar ik "from dt_auto" heb gewijzigd in "from pandas". Dit is voldoende zolang u alleen "=read_csv()" gebruikt en het niet kwalificeert als "=pd.read_csv()" of "=dt_auto.read_csv()".

Hier is de inhoud van mijn dt_auto.py ("datetime automatisch"):

import pandas as pd
def dt_inplace(df): """Automatically detect and convert (in place!) each dataframe column of datatype 'object' to a datetime just when ALL of its non-NaN values can be successfully parsed by pd.to_datetime(). Also returns a ref. to df for convenient use in an expression. """ from pandas.errors import ParserError for c in df.columns[df.dtypes=='object']: #don't cnvt num try: df[c]=pd.to_datetime(df[c]) except (ParserError,ValueError): #Can't cnvrt some pass # ...so leave whole column as-is unconverted return df
def read_csv(*args, **kwargs): """Drop-in replacement for Pandas pd.read_csv. It invokes pd.read_csv() (passing its arguments) and then auto- matically detects and converts each column whose datatype is 'object' to a datetime just when ALL of the column's non-NaN values can be successfully parsed by pd.to_datetime(), and returns the resulting dataframe. """ return dt_inplace(pd.read_csv(*args, **kwargs))

Maar is dit niet riskant? Wat als een van de kolommen niet helemaal een datum/tijd-kolom was? Natuurlijk kun je enkele obscure strings hebben die er toevallig uitzien als datums, maar dat niet zijn, maar er is niet veel risico dat deze code blindelings niet-datetime-strings converteert of verliest, en wel om twee redenen:

  1. Deze code zal niet converteer alle waarden in een kolom tenzij elk niet-NaN-waarde in deze kolom kan met succes worden geparseerd door pd.to_datetime en geconverteerd naar een datetime. Met andere woorden, we laten het nooit een string converteren naar een pd.NaT (het “mislukte” resultaat) omdat het het niet kan begrijpen als een datum/tijd.
  2. Het zal niet probeer kolommen te converteren die al zijn geïnterpreteerd als een ander type dan object, dwz een specifiek type zoals int64 of float64, ook al zou pd.to_datetime graag (maar waarschijnlijk onwenselijk) een getal als 2000 hebben omgezet naar de datum 2000-01 -01.

In mijn ervaring tot nu toe duurt het niet lang voordat de functie dt_auto.read_csv wordt uitgevoerd op een typisch dataframe. Zelfs als er veel niet-datetime-objectkolommen (tekenreeks) zijn, komt het bijna altijd heel snel een waarde tegen aan de bovenkant van elke dergelijke kolom die het niet kan ontleden als een datetime en geeft het op en gaat door naar de volgende kolom zonder te proberen de rest van de kolomwaarden te ontleden.

Hier is hoe het resulterende dataframe eruit ziet van dt_auto.read_csv(), hoewel je niet noodzakelijkerwijs kunt zien door ernaar te kijken dat de twee juiste kolommen inderdaad datetime datatypes zijn. Toevallig had het CSV-bestand een wisselend aantal decimalen (drie, geen en negen) voor de seconden in Update_Timestamp, maar het datatype datetime zelf toont hoe dan ook negen van dergelijke cijfers. Geboortedatum in het csv-bestand had eigenlijk alleen datums (geen tijden) maar werd opgeslagen als een volledige datumtijd, met nullen voor de uren, minuten en seconden (inclusief nul als het decimale deel), maar alle tijdcomponenten in de kolom nul zijn zorgt ervoor dat Panda's alleen de datum (jaar-maand-dag) voor deze kolom weergeeft.



Natuurlijk kan pd.to_datetime, en dus dt_auto.read_csv, standaard niet alle mogelijke datum- en datum/tijd-formaten aan, maar het zal veel voorkomende ondubbelzinnige (meestal jaar maand dag) formaten aan, zoals die geschreven door de dataframe.to_csv methode en vele andere tools, waaronder veel ISO-datetime-indelingen (die over het algemeen een "T" hebben die de datum van de tijd scheidt in plaats van een spatie). Ik heb niet geëxperimenteerd met datetimes die tijdzone-informatie bevatten, omdat ik dergelijke gegevens meestal niet zie, maar laat me alsjeblieft in een reactie weten of deze beter kunnen worden afgehandeld door verdere wijzigingen in de code.

Wat denk je? Vond je dit kleine artikel nuttig? En moet Pandas zelf (bijv. aan de pd.read_csv-functie zelf?) de mogelijkheid toevoegen om dit optioneel voor ons te doen, zodat u mijn dt_auto.py-code hierboven niet hoeft te kopiëren/importeren? Ik zie uw opmerkingen en vragen graag als antwoorden hier.

 
Met dank aan Elliot Gunn.

 
Bio: David B. Rosen (PhD) is Lead Data Scientist voor Automated Credit Approval bij IBM Global Financing. Vind meer van David's schrijven op dabruro.medium.com.

ORIGINELE. Met toestemming opnieuw gepost.

Zie ook:

Bron: https://www.kdnuggets.com/2021/10/auto-detect-date-datetime-columns-and-set-their-datatype-when-reading-a-csv-file-in-pandas.html

Tijdstempel:

Meer van KDnuggets