Jan Jan - 2 months ago 21
Python Question

Clean data in pandas

I have the following dataframe:

Datum Unternehmen Event
0 9 Termine vom 01.01.2016 bis zum 31.12.2017 9 Termine vom 01.01.2016 bis zum 31.12.2017 NaN
1 9 Termine vom 01.01.2016 bis zum 31.12.2017 NaN NaN
2 Datum Unternehmen Event
3 12.05.2017 ADIDAS AG Dividenden
4 09.11.2017 ADIDAS AG Ergebnisberichte
5 03.08.2017 ADIDAS AG Ergebnisberichte
6 11.05.2017 ADIDAS AG Hauptversammlung
7 04.05.2016 ADIDAS AG Ergebnisberichte
8 03.03.2016 ADIDAS AG Ergebnisberichte
9 04.08.2016 ADIDAS AG Ergebnisberichte
10 03.11.2016 ADIDAS AG Ergebnisberichte
11 12.05.2016 ADIDAS AG Hauptversammlung


And I want to keep the rows(!) with an apparent date only.

At the moment, I am iterating with
df.iterrows()
and check the value with a regular expression (
r'^[\d.]+$'
) but I wonder if there's a more "pythonic way" as
iterrows()
is very slow when applied to a couple of hundred dataframes.

Answer

I think you can use to_datetime with parameter errors='coerce' and check where are not NaN with boolean indexing:

print (pd.to_datetime(df.Datum, errors='coerce'))
0           NaT
1           NaT
2           NaT
3    2017-12-05
4    2017-09-11
5    2017-03-08
6    2017-11-05
7    2016-04-05
8    2016-03-03
9    2016-04-08
10   2016-03-11
11   2016-12-05
Name: Datum, dtype: datetime64[ns]

print (pd.to_datetime(df.Datum, errors='coerce').notnull())
0     False
1     False
2     False
3      True
4      True
5      True
6      True
7      True
8      True
9      True
10     True
11     True
Name: Datum, dtype: bool
print (df[pd.to_datetime(df.Datum, errors='coerce').notnull()])
         Datum Unternehmen             Event
3   12.05.2017   ADIDAS AG        Dividenden
4   09.11.2017   ADIDAS AG  Ergebnisberichte
5   03.08.2017   ADIDAS AG  Ergebnisberichte
6   11.05.2017   ADIDAS AG  Hauptversammlung
7   04.05.2016   ADIDAS AG  Ergebnisberichte
8   03.03.2016   ADIDAS AG  Ergebnisberichte
9   04.08.2016   ADIDAS AG  Ergebnisberichte
10  03.11.2016   ADIDAS AG  Ergebnisberichte
11  12.05.2016   ADIDAS AG  Hauptversammlung

If need convert column Datum to datetime:

df.Datum = pd.to_datetime(df.Datum, errors='coerce')

print (df.Datum.notnull())
0     False
1     False
2     False
3      True
4      True
5      True
6      True
7      True
8      True
9      True
10     True
11     True
Name: Datum, dtype: bool

print (df[df.Datum.notnull()])
        Datum Unternehmen             Event
3  2017-12-05   ADIDAS AG        Dividenden
4  2017-09-11   ADIDAS AG  Ergebnisberichte
5  2017-03-08   ADIDAS AG  Ergebnisberichte
6  2017-11-05   ADIDAS AG  Hauptversammlung
7  2016-04-05   ADIDAS AG  Ergebnisberichte
8  2016-03-03   ADIDAS AG  Ergebnisberichte
9  2016-04-08   ADIDAS AG  Ergebnisberichte
10 2016-03-11   ADIDAS AG  Ergebnisberichte
11 2016-12-05   ADIDAS AG  Hauptversammlung`