2

I was wondering whether there is an elegant or perhaps more easier way to call a list of methods on the same object in python, rather writing it repeatedly each time. For example:

df['date_col'] = pd.to_datetime(df['date_col'])
df['date_col_day'] = df['date_col'].dt.day
df['date_col_month'] = df['date_col'].dt.month
df['date_col_year'] = df['date_col'].dt.year

could be substituted with some more elegant like

for method in [day, month, year]:
    df[method.name] = df['date_col'].dt.method

I know the above example is syntactically incorrect, its just a demonstration of how I want it to be.

Is is possible?

Nikhil Mishra
  • 1,182
  • 2
  • 18
  • 34

1 Answers1

2

If you had a number of functions to be called as a "cascade", i.e.:

  • y1 = fun1(df.x)
  • y2 = fun1(y1)
  • y3 = fun1(y2)

you could use y3 = df.pipe(fun1).pipe(fun2).pipe(fun3).

In your case however the situation is different, because you want to save each partial result in a relevant column.

So instead you should apply a function generating a Series, with each partial result under a relevant index.

Example: The source DataFrame is:

     date_col  Xxx     Yyy
0  2019-01-12  100   97.37
1  2019-01-16  100   86.15
2  2019-01-20   80   80.00
3  2019-01-23  100  100.00

(date_col is of string type).

Define the following conversion function:

def conv(str):
    datTim = pd.to_datetime(str)
    return pd.Series([datTim, datTim.day, datTim.month, datTim.year],
        index=['date_col', 'date_col_day', 'date_col_month', 'date_col_year'])

And apply it the following way:

dtc = df.pop('date_col')
df = dtc.apply(conv).join(df)

Note that pop retrieves the given column, removing it from df. Then you apply conv to this column, generating a DataFrame, with 4 columns (the date and its "parts"). The last step is to join it with the "rest" of the source DataFrame (the columns left after dat_col was removed).

Now date_col is of datetime64 type and its content is:

    date_col  date_col_day  date_col_month  date_col_year  Xxx     Yyy
0 2019-01-12            12               1           2019  100   97.37
1 2019-01-16            16               1           2019  100   86.15
2 2019-01-20            20               1           2019   80   80.00
3 2019-01-23            23               1           2019  100  100.00
Valdi_Bo
  • 30,023
  • 4
  • 23
  • 41