title: How do I efficiently apply pandas.Timestamp functions to a full dataframe/column?
body: <p>Pandas is a great tool for a number of data tasks. Many functions have been streamlined to efficiently be applied to columns rather than individual cells/rows. One such function is the <code>to_datetime()</code> function, which I use as an example later in this question. However, <strong>there are a number of commands in pandas that, as best I can tell from the documentation, do not directly relate to dataframes.</strong> The specific function I am interested in is the <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.isocalendar.html" rel="nofollow noreferrer"><code>pandas.Timestamp.isocalendar()</code></a> function, but there are a slew of functions in the <code>pandas.Timestamp</code> class (and likely other pandas classes as well) that fit this description and have minimal documentation. <strong>Is there a way to efficiently broadcast these functions to a full column's worth of data?</strong> If so, how would I do that?</p>
  <p>Note: I know that I can use the <code>apply()</code> function, but this is demonstrably slower (~5x in my test) than what I have in mind. The <code>apply()</code> function is also not restricted to pandas functions, so I feel there must be a way to do this (otherwise, why have the <code>pandas.Timestamp</code> class at all, when <code>datetime</code> does these same things for single values?). See the below code for an example, in which I compare the <code>pandas.to_datetime()</code> function to applying the <code>datetime.strptime()</code> function to each row.</p>
  <pre><code>import pandas as pd
  import datetime
  from faker import Faker
  import time
  import copy
  
  # Setting up fake dataframe:
  Faker.seed(0)
  fake = Faker()
  
  observations=1000
  
  dates=[fake.date_between(start_date=datetime.datetime(2020,1,1),end_date=datetime.datetime(2020,1,31)) for _ in range(observations)]
  index=[x for x in range(observations)]
  
  df=pd.DataFrame({'id' : index,'dates' : dates},columns=['id','dates'])
  
  # Converting datetime object to string:
  df['dates']=df['dates'].apply(lambda x: x.strftime('%Y-%m-%d'))
  
  # Copy dataframe to run two time tests:
  df2=copy.copy(df)
  
  # Speed of the apply() function:
  tic = time.perf_counter()
  df['dates']=df['dates'].apply(lambda x: datetime.datetime.strptime(x,'%Y-%m-%d'))
  toc = time.perf_counter()
  print(f'pandas apply(lambda) completed in {toc-tic:0.4f} seconds')
  
  # speed of the to_datetime() function:
  tic = time.perf_counter()
  df2['dates']=pd.to_datetime(df2['dates'],format='%Y-%m-%d')
  toc = time.perf_counter()
  print(f'pandas to_datetime() completed in {toc-tic:0.4f} seconds')
  
  #Script returns:
  #pandas apply(lambda) completed in 0.0107 seconds
  #pandas to_datetime() completed in 0.0021 seconds
  </code></pre>