Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
331 views

Cheat Sheet: The Pandas Dataframe Object: Column Index (DF - Columns)

This document provides a cheat sheet on loading, manipulating, and saving Pandas DataFrame objects. It describes how to load DataFrames from Excel files, SQL databases, Python dictionaries, and random NumPy arrays. It also explains how to get data into a DataFrame from Series, and how to save DataFrames to CSV and Excel files. Series objects contain ordered, one-dimensional data while DataFrames are two-dimensional tables containing Series in each column.

Uploaded by

Nirmala Shinde
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
331 views

Cheat Sheet: The Pandas Dataframe Object: Column Index (DF - Columns)

This document provides a cheat sheet on loading, manipulating, and saving Pandas DataFrame objects. It describes how to load DataFrames from Excel files, SQL databases, Python dictionaries, and random NumPy arrays. It also explains how to get data into a DataFrame from Series, and how to save DataFrames to CSV and Excel files. Series objects contain ordered, one-dimensional data while DataFrames are two-dimensional tables containing Series in each column.

Uploaded by

Nirmala Shinde
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

 

Cheat  Sheet:  The  Pandas  DataFrame  Object  


 
  Load  a  DataFrame  from  a  Microsoft  Excel  file  
Preliminaries   #  put  each  Excel  workbook  in  a  dictionary  
  workbook  =  pd.ExcelFile('file.xls')  
  d  =  {}  
Start  by  importing  these  Python  modules   for  name  in  workbook.sheet_names:  
import  numpy  as  np                                #  required          df  =  workbook.parse(name)  
import  pandas  as  pd                              #  required          d[name]  =  df  
from  pandas  import  DataFrame,  Series  #  useful    
  Load  a  DataFrame  from  a  MySQL  database  
  import  MySQLdb  as  db  
  import  pandas.io.sql  as  ps  
The  conceptual  model   cx  =  db.connect('localhost',  'username',    
                                         'password',  'database')  
df  =  ps.frame_query('SELECT  *  FROM  data',  cx)  
 
Series  object:  an  ordered,  one-­‐dimensional    
array  of  data  with  an  index.  All  the  data  in   Get  a  DataFrame  from  a  Python  dictionary  
a  Series  is  of  the  same  data  type.  Series   #  default  –  assume  your  data  in  columns  
arithmetic  is  vectorised  after  first  aligning   df  =  DataFrame({    
the  Series  index  for  each  of  the  operands.                  'col0'  :  [1.0,  2.0,  3.0,  4.0],    
s1  =  Series(range(0,4))    #  -­‐-­‐>  0,  1,  2,  3                  'col1'  :  [100,  200,  300,  400]      
s2  =  Series(range(1,5))    #  -­‐-­‐>  1,  2,  3,  4          })  
s3  =  s1  +  s2                          #  -­‐-­‐>  1,  3,  5,  7    
s4  =  Series(['a','b'])*3  #  -­‐-­‐>  'aaa',  'bbb'   #  use  helper  method  for  data  in  rows  
  df  =  DataFrame.from_dict({  #  data  by  row  
DataFrame  object:  a  two-­‐dimensional  table  of                  'row0'  :  {'col0':0,  'col1':'A'},  
data  with  column  and  row  indexes.  The  columns                  'row1'  :  {'col0':1,  'col1':'B'}  
are  made  up  of  pandas  Series  objects.          },  orient='index')  
 
 
df  =  DataFrame.from_dict({  #  data  by  row  
 
Column  index  (df.columns)                  'row0'  :  [1,  1+1j,  'A'],  
 
               'row1'  :  [2,  2+2j,  'B']  
       },  orient='index')  
Series  of  data  

Series  of  data  

Series  of  data  

Series  of  data  

Series  of  data  

Series  of  data  

Series  of  data  

 
(df.index)  
Row  index  

Create  play  data  (useful  for  testing)  


#  created  from  a  2D  numpy  array  (of  randoms)  
df  =  DataFrame(np.random.randn(26,5),    
       columns=['col'+str(i)  for  i  in  range(5)],  
       index=list("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))  
df['cat']  =  list('aaaabbbccddef'  *  2)  
   
   
   
Get  your  data  into  a  DataFrame   Saving  a  DataFrame  
   
   
Data  in  Series  then  combine  into  a  DataFrame   Writing  DataFrames  to  CSV  
#  Exmaple  1  ...   df.to_csv('filename.csv',  encoding='utf-­‐8')  
s1  =  Series(range(6))    
s2  =  s1  *  s1   Writing  DataFrames  to  Excel  
s2.index  =  s2.index  +  2  #  misaligned  indexes   from  pandas  import  ExcelWriter  
df  =  pd.concat([s1,  s2],  axis=1)   writer  =  ExcelWriter('filename.xlsx')  
  df1.to_excel(writer,'Sheet1')  
#  Exmaple  2  ...   df2.to_excel(writer,'Sheet2')  
s3  =  Series({'Tom':1,  'Dick':4,  'Harry':9})   writer.save()  
s4  =  Series({'Tom':3,  'Dick':2,  'Mary':11})    
df  =  pd.concat({'A':  s3,  'B':  s4  },  axis=1)   Writing  DataFrames  to  MySQL  
Note:  1st  method  has  in  integer  column  labels   import  MySQLdb  as  db  
Note:  2nd  method  does  not  guarantee  col  order   cx  =  db.connect('localhost',  'username',    
Note:  index  alignment  on  DataFrame  creation                                          'password',  'database')  
  df.to_sql(name='tablename',  con=cx,    
Load  a  DataFrame  from  a  CSV  file          flavour='mysql',  if_exists='replace')  
df  =  pd.read_csv('file.csv')   Note:  if_exists  –  'fail',  'replace',  'append'  

Version  16  August  2014  -­‐  [Draft]   1  


 
   
   
Working  with  row  and  column  indexes   Working  with  columns  of  data  (axis=1)  
   
   
DataFrames  have  two  Indexes   A  DataFrame  column  is  a  pandas  Series  object  
Typically,  the  column  index  is  a  list  of    
strings  (observed  variable  names)  or  (less   Selecting  columns    
commonly)  integers.  The  row  index  might  be   s  =  df['colName']          #  select  column  by  name  
• Integers  -­‐  for  case  or  row  numbers  (default   df  =  df[['a','b']]        #  select  2  or  more  cols  
is  numbered  from  0  to  length-­‐1)   df  =  df[['c','a','b']]#  change  column  order  
• Strings  –  for  case  names   s  =  df[df.columns[0]]  #  select  column  by  num  
• DatetimeIndex  or  PeriodIndex  –  for  time    
series  data  (more  on  these  indexes  below)   Selecting  columns  with  Python  attributes  
 
s  =  df.a                            #  same  as  s  =  df['a']  
Get  column  index  and  labels   df.existing_col  =  df.a  /  df.b  
idx  =  df.columns                            #  get  col  index   #  cannot  create  new  columns  by  attribute  ...  
label  =  df.column[0]                    #  1st  col  label   df['new_col']  =  df.a  /  df.b    
lst  =  df.columns.tolist()          #  get  as  a  list   Trap:  column  names  must  be  valid  identifiers.  
   
Change  column  labels   Adding  new  columns  to  a  DataFrame  
df.rename(columns={'old':'new'},inplace=True)   df['new_col']  =  range(len(df))  
df  =  df.rename(columns  =  {'a':'a1','b':'b2'})   df['new_col']  =  np.repeat(np.nan,  len(df))  
  df['random']  =  np.random.rand(len(df))  
Get  the  row  index  and  labels   df['index_as_col']  =  df.index  
idx  =  df.index                                #  get  row  index   df1[['b','c']]  =  df2[['e','f']]      #  multi  add  
st
label  =  df.index[0]                      #  1  row  label   df3  =  df1.append(other=df2)              #  multi  add  
lst  =  df.index.tolist()              #  get  as  a  list    
  Swap  column  contents  
Change  the  (row)  index   df[['B',  'A']]  =  df[['A',  'B']]  
df.index  =  idx                          #  new  ad  hoc  index    
df.index  =  range(len(df))    #  set  with  list   Dropping  columns  (by  label)  
df  =  df.reset_index()  #  replace  old  with  new   df  =  df.drop('col1',  axis=1)    
         #  note:  old  index  stored  as  a  col  in  df   df.drop('col1',  axis=1,  inplace=True)  
df  =  df.reindex(index=range(len(df)))   df  =  df.drop(['col1','col2'],  axis=1)  #  multi  
df  =  df.set_index(keys=['col1','col2','etc'])   s  =  df.pop('col')  #  get  col;  drop  from  frame  
df.rename(index={'old':'new'},  inplace=True)   del  df['col']          #  even  classic  python  works  
   
Get  the  integer  position  of  a  row  index  label   Selecting  columns  with  .loc,  .iloc  and  .ix  
i  =  df.index.get_loc('label')  #  also  columns   df  =  df.loc[:,  'col1':'col2']  #inclusive  "to"  
  df  =  df.iloc[:,  0:2]                    #exclusive  "to"  
Sort  DataFrame  by  its  row  or  column  index   A  slice  of  columns  can  be  selected  by  label  
df.sort_index(inplace=True)  #  sort  by  rows   (using  df.loc[rows,  cols]);  by  integer  
df  =  df.sort_index(axis=1)    #  sort  by  cols   position  (using  df.iloc[rows,  cols]);  or  a  
  hybrid  of  the  two  (using  df.ix[rows,  cols])  
Test  if  the  index  values  are  unique/monotonic   Note:  the  row  slice  object  :  copies  all  rows  
if  df.index.is_unique:  pass  #  do  something     Note:  For  .loc,  the  indexes  can  be:  
if  df.columns.is_unique:  pass  #  do  something   • A  single  label  (eg.  'A')  
if  df.index.is_monotonic:  pass  #  do  something   • A  list/array  of  labels  (eg.  ['A',  'B'])  
if  df.  columns.is_monotonic:  pass  #  something   • A  slice  object  of  labels  (eg.  'A':'C')  
For  a  monotonic  index,  each  element  is   • A  Boolean  array  
greater  than  or  equal  to  the  previous  element   Note:  For  .iloc,  the  indexes  can  be  
  • A  single  integer  (eg.  27)  
Drop  duplicates  in  the  row  index   • A  list/array  of  integers  (eg.  [1,  2,  6])  
df['index']  =  df.index          #  1  create  new  col   • A  slice  object  with  integers  (eg.  1:9)  
df  =  df.drop_duplicates(cols='index',      
               take_last=True)        #  2  use  new  col   Vectorised  arithmetic  on  columns  
del  df['index']                        #  3  del  the  col   df['proportion']  =  df['count']  /  df['total']  
df.sort_index(inplace=True)#  4  tidy  up   df['percent']  =  df['proportion']  *  100.0  
   
Test  if  two  DataFrames/Series  have  same  index   Apply  numpy  mathematical  functions  to  columns  
len(a)  ==  len(b)  and  all(a.index  ==  b.index)   df['log_data']  =  np.log(df['col1'])  
df['rounded']  =  np.round(df['col2'],  2)  

Version  16  August  2014  -­‐  [Draft]   2  


 
   
Columns  value  set  based  on  criteria    
#  Option  1:  using  a  mask     Working  with  rows  (axis=0)  
df['new']  =  0    
df[df['c']  >  0]['new']  =  df['c']    
#  Option  2:  using  the  where  statement   Adding  rows  
df['new']  =  df['c'].where(df['c']>0,  other=0)   df  =  original_df.append(more_rows_in_df)  
Note:  Multiple  conditions  can  be  combined   Hint:  convert  to  a  DataFrame  and  then  append.  
using  &  and  |  with  conditions  in  parentheses.   Both  DataFrames  should  have  same  col  labels.  
Note:  where  other  can  be  a  Series  or  a  scalar    
Note:  ~  the  boolean  not  operator  for  pandas   Dropping  rows  (by  name)  
  df  =  df.drop('row_label')    
Iterating  over  the  Dataframe  cols   df  =  df.drop(['row1','row2'])          #  multi-­‐row  
for  (column,  series)  in  df.iteritems():    
       #  do  something  ...   Boolean  row  selection  by  values  in  a  column  
Where  column  is  the  label  and  series  is  a   df  =  df[df['col2']  >=  0.0]  
pandas  Series  that  contains  the  column  data.   df  =  df[(df['col3']>=1.0)  |  (df['col1']<0.0)]  
  df  =  df[df['col'].isin([1,2,5,7,11])]  
Common  column-­‐wide  methods/attributes   df  =  df[~df['col'].isin([1,2,5,7,11])]  #  not  
value  =  df['col1'].dtype          #  type  of  data   df  =  df[df['col'].str.contains('hello')]  
value  =  df['col1'].size            #  col  dimensions   Trap:  bitwise  "or"  and  "and"  co-­‐opted  to  be  
value  =  df['col1'].count()      #  non-­‐NA  count   Boolean  operators  on  a  Series  of  Boolean  -­‐-­‐>  
value  =  df['col1'].sum()   also  note  parentheses  around  comparisons.  
value  =  df['col1'].prod()    
value  =  df['col1'].min()   Select  a  slice  of  rows  by  integer  position  
value  =  df['col1'].max()   [inclusive-­‐from  :  exclusive-­‐to]  
value  =  df['col1'].mean()   [inclusive-­‐from  :  exclusive-­‐to  :  step]  
value  =  df['col1'].median()   default  start  is  0;  default  end  is  len(df)  
value  =  df['col1'].cov(df['col2'])  
df  =  df[:]              #  copy  DataFrame  
s  =          df['col1'].describe()  
df  =  df[0:2]          #  rows  0  and  1  
s  =          df['col1'].value_counts()  
df  =  df[-­‐1:]          #  the  last  row  
  df  =  df[2:3]          #  row  2  (the  third  row)  
Find  index  for  min/max  values  in  column   df  =  df[:-­‐1]          #  all  but  the  last  row  
value  =    df['col1'].idxmin()  #  returns  label   nd
df  =  df[::2]          #  every  2  row  (0  2  ..)  
value  =    df['col1'].idxmax()  #  returns  label   Trap:  a  single  integer  without  a  colon  is  a  
  column  index  for  numbered  columns.    
Common  column  element-­‐wise  methods    
s  =  df['col'].to_datetime()   Select  a  slice  of  rows  by  label/index  
s  =  df['col1'].isnull()    [inclusive-­‐from  :  inclusive–to  [  :  step]]  
s  =  df['col1'].notnull()  #  not  isnull()   df  =  df['a':'c']  #  rows  'a'  through  'c'  
s  =  df['col1'].astype('float')  #  type  convert   Trap:  doesn't  work  on  integer  labelled  rows    
s  =  df['col1'].round(decimals=0)    
s  =  df['col1'].diff(periods=1)   Append  a  row  of  column  totals  to  a  DataFrame  
s  =  df['col1'].shift(periods=1)  
#  Option  1:  using  a  dictionary  comprehension  
s  =  df['col1'].fillna(0)  #  replace  NaN  with  0  
sums  =  {col:  df[col].sum()  for  col  in  df}  
s  =  df['col1'].  pct_change(periods=4)  
sums_df  =  DataFrame(sums,  index=['Total'])  
s  =  df['c'].rolling_min(periods=4,  window=4)  
df  =  df.append(sums_df)  
s  =  df['c'].rolling_max(periods=4,  window=4)  
#  Option  2:  All  done  with  pandas  
s  =  df['c'].rolling_sum(periods=4,  window=4)  
df  =  df.append(DataFrame(df.sum(),    
           columns=['Total']).T)  #  .T  is  transpose  
Append  a  column  of  row  totals  to  a  DataFrame  
 
df['Total']  =  df.sum(axis=1)   Iterating  over  DataFrame  rows  
Note:  can  do  row  means,  mins,  maxs,  etc.  in  a   for  (index,  row)  in  df.iterrows():  
similar  manner.  
Trap:  row  data  type  may  be  coerced.  
 
 
Group  by  a  column  
Sorting  DataFrame  rows  by  column  values  
s  =  df.groupby('cat')['col1'].sum()  
df  =  df.sort(df.columns[0],  ascending=False)  
dfg  =  df.groupby('cat').sum()  
df.sort(['col1',  'col2'],  inplace=True)  
 
 
Group  by  a  row  index  (non-­‐hierarchical  index)  
Remember!  
df  =  df.set_index(keys='cat')  
w  =  df['label']                    #  a  selected  column  
s  =  df.groupby(level=0)['col1'].sum()  
x  =  df[['L1',  'L2']]          #  selected  columns  
dfg  =  df.groupby(level=0).sum()  
y  =  df['label':'label']    #  selected  rows  
  z  =  df[i:j]  #  where  i  &  j  are  ints,  à  rows  

Version  16  August  2014  -­‐  [Draft]   3  


 
   
   
Working  with  cells   Joining/Combining  DataFrames  
   
   
Selecting  a  cell  by  row  and  column  labels   Three  ways  to  join  two  DataFrames:  
value  =  df.at['row',  'col']   • merge  (a  database/SQL-­‐like  join  operation)  
value  =  df.loc['row',  'col']   • concat  (stack  side  by  side  or  stack  one  on  
value  =  df['col']['row']                          #  tricky   top  of  the  other)  
Note:  .at[]  fastest  label  based  scalar  lookup   • combine_first  (splice  the  two  togther,  
  choosing  values  from  one  over  the  other)  
Setting  a  cell  by  row  and  column  labels    
df.at['row,  'col']  =  value   Merge  on  indexes  
df.loc['row,  'col']  =  value   df_new  =  pd.merge(left=df1,  right=df2,  
df['col']['row']  =  value                          #  tricky      how='outer',  left_index=True,  
     right_index=True)  
Selecting  and  slicing  on  labels   How:  'left',  'right',  'outer',  'inner'  
df  =  df.loc['row1':'row3',  'col1':'col3']   How:  outer=union/all;  inner=intersection  
Note:  the  "to"  on  this  slice  is  inclusive.    
  Merge  on  columns  
Setting  a  cross-­‐section  by  labels   df_new  =  pd.merge(left=df1,  right=df2,  
df.loc['A':'C',  'col1':'col3']  =  np.nan   how='left',  left_on='col1',  right_on='col2')  
df.loc[1:2,  'col1':'col2']  =  np.zeros((2,2))   Trap:  When  joining  on  columns,  the  indexes  on  
df.loc[1:2,  'A':'C']  =  other.loc[1:2,'A':'C']   the  passed  DataFrames  are  ignored.  
Remember:  inclusive  from:to  in  the  slice   Trap:  many-­‐to-­‐many  merges  on  a  column  can  
  result  in  an  explosion  of  associated  data.  
Selecting  a  cell  by  integer  position    
Join  on  indexes  (another  way  of  merging)  
value  =  df.iat[9,  3]                          #  [row,  col]  
value  =  df.iloc[0,  0]                        #  [row,  col]   df_new  =  df1.join(other=df2,  on='col1',    
value  =  df.iloc[len(df)-­‐1,  len(df.columns)-­‐1]                                        how='outer')  
  df_new  =  df1.join(other=df2,  on=['a',  'b'],  
Selecting  a  range  of  cells  by  int  position                                        how='outer')  
df  =  df.iloc[2:4,  2:4]#  a  subset  of  the  df   Note:  DataFrame.join()  joins  on  indexes  by  
df  =  df.iloc[:5,  :5]    #  top  left  corner   default.  DataFrame.merge()  joins  on  common  
s  =  df.iloc[5,  :]          #  returns  row  as  Series   columns  by  default.    
 
df  =  df.iloc[5:6,  :]    #  returns  row  as  a  row  
Simple  concatenation  is  often  the  best  
Note:  exclusive  "to"  –  same  as  list  slicing.  
  df=pd.concat([df1,df2],axis=0)  #  top/bottom  
Setting  cell  by  integer  position   df  =  df1.append([df2,  df3])        #  top/bottom  
df=pd.concat([df1,df2],axis=1)  #  left/right  
df.iloc[0,  0]  =  value                        #  [row,  col]  
df.iat[7,  8]  =  value   Trap:  can  end  up  with  duplicate  rows  or  cols  
Note:  concat  has  an  ignore_index  parameter  
 
 
Setting  cell  range  by  integer  position  
Combine_first  
df.iloc[0:3,  0:5]  =  value  
df  =  df1.combine_first(other=df2)  
df.iloc[1:3,  1:4]  =  np.ones((2,3))  
df  =  reduce(lambda  x,  y:  x.combine_first(y),    
Remember:  exclusive  from:to  in  the  slice                [df1,  df2,  df3,  df4,  df5])  
 
Uses  the  non-­‐null  values  from  df1.  The  index  
Operate  on  the  whole  DataFrame  
of  the  combined  DataFrame  will  be  the  union  
#  replace  np.nan  with  0   of  the  indexes  from  df1  and  df2.  
df.fillna(0,  inplace=True)    
#  replace  white  space  with  np.nan    
df  =  df.replace(r'\s+',  np.nan,  regex=True)  
 
  Working  with  the  whole  DataFrame  
Views  and  copies    
From  the  manual:  The  rules  about  when  a  view  
 
on  the  data  is  returned  are  dependent  on  
Peek  at  the  DataFrame  
NumPy.  Whenever  an  array  of  labels  or  a  
boolean  vector  are  involved  in  the  indexing   summary_df  =  df.describe()  
operation,  the  result  will  be  a  copy.  A   head_df  =  df.head();  tail_df  =  df.tail()  
single  label/scalar  indexing  &  slicing,  e.g.   top_left_corner_df  =  df.iloc[:5,  :5]  
df.ix[3:6]  or  df.ix[:,  'A'],  returns  a  view.    
Other  useful  
df  =  df.T                #  transpose  rows  and  columns  
df2  =  df.copy()    #  copy  a  DataFrame  

Version  16  August  2014  -­‐  [Draft]   4  


 
   
  Error  handling  with  dates  
Working  with  dates,  times  and  their  indexes   #  first  example  returns  string  not  Timestamp  
  s  =  pd.to_datetime('2014-­‐02-­‐30')  
  #  second  example  returns  NaT  (not  a  time)  
Dates  and  time  –  points  and  spans   n  =  pd.to_datetime('2014-­‐02-­‐30',  coerce=True)    
With  its  focus  on  time-­‐series  data,  pandas   #  NaT  is  like  NaN  ...  tests  True  for  isnull()  
provides  a  suite  of  tools  for  managing  dates   b  =  pd.isnull(n)  #  -­‐-­‐>  True  
and  time:  either  as  a  point  in  time  (a    
Timestamp)  or  as  a  span  of  time  (a  Period).     Creating  date/period  indexes  from  scratch  
timestamp  =  pd.Timestamp('2013-­‐01-­‐01')   dt_idx  =  pd.DatetimeIndex(pd.date_range(  
period  =  pd.Period('2013-­‐01-­‐01',  freq='M')          start='1/1/2011',    periods=12,  freq='M'))  
  p_idx  =  pd.period_range('1960-­‐01-­‐01',  
Dates  and  time  –  stamps  and  spans  as  indexes              '2010-­‐12-­‐31',  freq='M')  
An  index  of  Timestamps  is  a  DatetimeIndex;    
and  an  index  of  Periods  is  a  PeriodIndex.   Row  selection  with  a  time-­‐series  index  
These  can  be  constructed  as  follows:   #  play  data  ...  start  with  play  data  above  
date_strs  =  ('2013-­‐10-­‐01',  '2013-­‐11-­‐01',   idx  =  pd.period_range('2013-­‐01',    
                         '2013-­‐12-­‐01',  '2014-­‐01-­‐01')   periods=len(df),  freq='M')  
tstamp  =  pd.to_datetime(pd.Series(date_strs))   df.index  =  idx    
dt_idx  =  pd.DatetimeIndex(tstamp,  freq='MS')    
prd_idx  =  pd.PeriodIndex(tstamp,  freq='M')   february_selector  =  (df.index.month  ==  2)  
spi  =  Series([1,2,3,4],  index=prd_idx)   february_data  =  df[february_selector]  
sdi  =  Series([1,2,3,4],  index=dt_idx)    
#  Also:  index  changed  through  its  attribute   q1_data  =  df[(df.index.month  >=  1)  &  
spi.index  =  dt_idx  #  change  to  time  stamps        (df.index.month  <=  3)]  #  note:  &  not  "and"  
spi.index  =  range(len(spi))  #  to  integers    
  mayornov_data  =  df[(df.index.month  ==  5)  |    
From  DatetimeIndex  and  PeriodIndex  and  back        (df.index.month  ==  11)]  #  note:  |  not  "or"  
spi  =  sdi.to_period(freq='M')#  to  PeriodIndex    
sdi  =  spi.to_timestamp()      #  to  DatetimeIndex   annual_tot  =  df.groupby(df.index.year).sum()  
Note:  from  period  to  timestamp  defaults  to   Also:  year,  month,  day  [of  month],  hour,  
the  point  in  time  at  the  start  of  the  period.   minute,  second,  dayofweek  [Mon=0  ..  Sun=6],  
  weekofmonth,  weekofyear  [numbered  from  1],  
Frequency  constants  (not  a  complete  list)   week  starts  on  Monday],  dayofyear  [from  1],  …    
Name   Description   Note:  this  method  works  with  both  Series  and  
DataFrame  objects.  
U   Microsecond    
 
L   Millisecond    
The  tail  of  a  time-­‐series  DataFrame  
S   Second    
df  =  df.last("5M")          #  the  last  five  months  
T   Minute    
 
H   Hour    
 
D   Calendar  day  
 
B   Business  day  
Working  with  strings  
W-­‐{MON,  TUE,  …}   Week  ending  on  …    
MS   Calendar  start  of  month    
M   Calendar  end  of  month   Working  with  strings  
QS-­‐{JAN,  FEB,  …}   Quarter  start  with  year   #  assume  that  df['col']  is  series  of  strings  
starting  (QS  –  December)   s  =  df['col'].str.lower()  
Q-­‐{JAN,  FEB,  …}   Quarter  end  with  year   s  =  df['col'].str.upper()  
ending  (Q  –  December)   s  =  df['col'].str.len()  
AS-­‐{JAN,  FEB,  …}   Year  start  (AS  -­‐  December)   df['col']  +=  'suffix'  #  add  text  to  each  row  
A-­‐{JAN,  FEB,  …}   Year  end  (A  -­‐  December)   df['col']  *=  2                #  repeat  text  
  s  =  df['col1']  +  df['col2']  #  concatenate  
More  examples  on  working  with  dates/times   Most  python  string  functions  are  replicated  
d  =  pd.to_datetime(['04-­‐01-­‐2012'],     in  the  pandas  DataFrame  and  Series  objects.  
           dayfirst=True)  #  Australian  date  format    
t  =  pd.to_datetime(['2013-­‐04-­‐01  15:14:13.1'])   Regular  expressions  
DatetimeIndex  can  be  converted  to  an  array  of   s  =  df['col'].str.contains('regex')  
Python  native  datetime.datetime  objects  using   s  =  df['col'].str.startswith('regex')  
the  to_pydatetime()  method.   s  =  df['col'].str.endswith('regex')  
s  =  df['col'].str.replace('old',  'new')  
Note:  pandas  has  many  more  regex  methods  

Version  16  August  2014  -­‐  [Draft]   5  


 
   
  Categorical  into  DataFrame  
Working  with  missing  and  non-­‐finite  data   You  can  put  a  column  of  encoded  Categorical  
  data  in  the  DataFrame,  but  in  the  process  the  
  factor  information  will  be  lost;  so  you  will  
Working  with  missing  data   need  to  hold  this  factor  information  outside  
Pandas  uses  the  not-­‐a-­‐number  construct   of  the  DataFrame.  
(np.nan  and  float('nan'))  to  indicate  missing   factor  =  pd.Categorical.from_array(df['cat'])  
data.  The  Python  None  can  arise  in  data  as   df['labels']  =  factor.labels  #  integers  only  
well.  It  is  also  treated  as  missing  data;  as   df['cat2']  =  factor  #  converts  back  to  string  
is  the  pandas  not-­‐a-­‐time  (pd.NaT)  construct.    
   
Missing  data  in  a  Series    
s  =  pd.Series([8,None,float('nan'),np.nan])   Basic  Statistics  
#  -­‐-­‐>                          [8,          NaN,    NaN,      NaN]    
s.isnull()  #  -­‐-­‐>  [False,  True,  True,    True]    
s.notnull()#  -­‐-­‐>  [True,  False,  False,  False]   Summary  statistics  
  s  =  df['col1'].describe()  
Missing  data  in  a  DataFrame   df1  =  df.describe()  
df  =  df.dropna()    #  drop  all  rows  with  a  NaN    
df  =  df.dropna(axis=1)  #  as  above  for  cols   Value  counts  
df=df.dropna(how='all')  #  only  if  all  in  row   s  =  df['col1'].value_counts()  
df=df.dropna(thresh=2)  #  at  least  2  NaN  in  r    
#  only  drop  row  if  NaN  in  a  specified  'col'   Cross-­‐tabulation  (frequency  count)  
df  =  df.dropna(df['col'].notnull())  
ct  =  pd.crosstab(index=df['a'],  cols=df['b'])  
 
 
Non-­‐finite  numbers  
Quantiles  and  ranking  
With  floating  point  numbers,  pandas  provides  
for  positive  and  negative  infinity.   q  =  df.quantile(q=[0.05,0.25,0.5,0.75,0.95])  
r  =  df.rank()  
s  =  Series([float('inf'),  float('-­‐inf'),    
         np.inf,  -­‐np.inf])  #  inf,  -­‐inf,  inf,  -­‐inf    
Histogram  binning  
Pandas  treats  integer  comparisons  with  plus  
or  minus  infinity  as  expected.   count,  bins  =  np.histogram(df['col1'])  
  count,  bins  =  np.histogram(df['col'],  bins=5)  
Testing  for  finite  numbers   count,  bins  =  np.histogram(df['col1'],    
(using  the  data  from  the  previous  example)                                        bins=[-­‐3,-­‐2,-­‐1,0,1,2,3,4])  
np.isfinite(s)  #  False,  False,  False,  False    
Correlation  and  covariance    
 
  df_cm  =  df.corr()  
df_cv  =  df.cov()  
 
Working  with  Categorical  Data    
  Regression  
  import  statsmodels.formula.api  as  sm  
Categorical  data   result  =  sm.ols(formula="col1  ~  col2  +  col3",    
The  pandas  Series  has  an  R  factors-­‐like  data                                      data=df).fit()  
type  for  encoding  categorical  data  into   print  (result.params)  
integers.     print  (result.summary())  
c  =  pd.Categorical.from_array(list)    
c.levels      #  -­‐-­‐>  the  coding  frame   Smoothing  example  using  rolling_apply  
c.labels      #  -­‐-­‐>  the  encoded  integer  array   k3x5  =  np.array([1,2,3,3,3,2,1])  /  15.0  
c.describe  #  -­‐-­‐>  the  values  and  levels   s  =  pd.rolling_apply(df['col1'],  window=7,  
                   func=lambda  x:  (x  *  k3x5).sum(),    
Indexing  categorical  data                      min_periods=7,  center=True)  
The  categorical  data  can  be  indexed  in  a  
manner  conceptually  similar  to  that  for  
Series.iloc[]  above:  
listy  =  ['a',  'b',  'a',  'b',  'b',  'c']    
c  =  pd.Categorical.from_array(listy)  
c.levels              #  -­‐-­‐>  ['a',  'b',  'c']  
c.labels              #  -­‐-­‐>  [0,  1,  0,  1,  1,  2]  
x  =  c[1]              #  -­‐-­‐>  'b'  
x  =  c[[0,1]]      #  -­‐-­‐>  ['a',  'b']  
x  =  c[0:2]          #  -­‐-­‐>  ['a',  'b']  

Version  16  August  2014  -­‐  [Draft]   6  

You might also like