title: shuffling/permutating a DataFrame in pandas
body: <p>What's a simple and efficient way to shuffle a dataframe in pandas, by rows or by columns? I.e. how to write a function <code>shuffle(df, n, axis=0)</code> that takes a dataframe, a number of shuffles <code>n</code>, and an axis (<code>axis=0</code> is rows, <code>axis=1</code> is columns) and returns a copy of the dataframe that has been shuffled <code>n</code> times. </p>
  
  <p><strong>Edit</strong>: key is to do this without destroying the row/column labels of the dataframe. If you just shuffle <code>df.index</code> that loses all that information. I want the resulting <code>df</code> to be the same as the original except with the order of rows or order of columns different.</p>
  
  <p><strong>Edit2</strong>: My question was unclear. When I say shuffle the rows, I mean shuffle each row independently. So if you have two columns <code>a</code> and <code>b</code>, I want each row shuffled on its own, so that you don't have the same associations between <code>a</code> and <code>b</code> as you do if you just re-order each row as a whole. Something like: </p>
  
  <pre><code>for 1...n:
    for each col in df: shuffle column
  return new_df
  </code></pre>
  
  <p>But hopefully more efficient than naive looping. This does not work for me:</p>
  
  <pre><code>def shuffle(df, n, axis=0):
          shuffled_df = df.copy()
          for k in range(n):
              shuffled_df.apply(np.random.shuffle(shuffled_df.values),axis=axis)
          return shuffled_df
  
  df = pandas.DataFrame({'A':range(10), 'B':range(10)})
  shuffle(df, 5)
  </code></pre>