title: Pandas scalar value getting and setting: ix or iat?
body: <p>I'm trying to figure out when to use different selecting methods in pandas DataFrame. In particular, I'm looking for accessing scalar values. I often hear <code>ix</code> being generally recommended. But in <a href="http://pandas.pydata.org/pandas-docs/dev/indexing.html#fast-scalar-value-getting-and-setting" rel="noreferrer">pandas documentation</a>
  it's recommended to use <code>at</code> and <code>iat</code> for fast scalar value accessing:</p>
  
  <p><code>Since indexing with [] must handle a lot of cases (single-label access, slicing, boolean indexing, etc.), it has a bit of overhead in order to figure out what you’re asking for. If you only want to access a scalar value, the fastest way is to use the</code>at<code>and iat methods, which are implemented on all of the data structures.</code> </p>
  
  <p>So, I would assume <code>iat</code> should be faster for getting and setting individual cells. However, after some tests, we found that <code>ix</code> would be comparable or faster for reading cells, while <code>iat</code> much faster for assigning values to cells.</p>
  
  <p>Is this behavior documented anywhere? Is it always the case and why does this happen? Does it have to do something with returning view or copy? I would appreciate if someone could put any light on this question and explain what is recommended for getting and setting cell values and why.</p>
  
  <p>Here are some tests using pandas (version 0.15.2). </p>
  
  <p>Just to make sure that this behavior is not a bug of this version, I also tested it on 0.11.0. I do not provide the results, but the trend is exactly the same - <code>ix being much faster for getting, and iat for setting individual cells</code>.   </p>
  
  <pre><code>import pandas as pd
  import numpy as np
  
  df = pd.DataFrame(np.random.rand(1000,2),columns = ['A','B'])
  idx = 0
  
  timeit for i in range(1000): df.ix[i,'A'] = 1
  timeit for i in range(1000): df.iat[i,idx] = 2
  
  &gt;&gt; 10 loops, best of 3: 92.6 ms per loop
  &gt;&gt; 10 loops, best of 3: 21.7 ms per loop
  
  timeit for i in range(1000): tmp = df.ix[i,'A'] 
  timeit for i in range(1000): tmp = df.iat[i,idx] 
  
  &gt;&gt; 100 loops, best of 3: 5.31 ms per loop
  &gt;&gt; 10 loops, best of 3: 19.4 ms per loop
  </code></pre>