2012-05-04 63 views
2

洗牌行我有一個熊貓DataFrame使用的行的MultiIndex大熊貓在一定水平

index = pandas.MultiIndex.from_tuples(list(itertools.product(range(3), range(3)))) 
df = pandas.DataFrame(numpy.random.randn(9,3), index=index, columns=['A', 'B', 'C']) 

      A   B   C 
0 0 2.400417 0.698638 1.231540 
    1 -0.023154 -2.110450 0.774964 
    2 -1.282392 -0.062794 1.471655 
1 0 -1.081853 0.261876 -1.771075 
    1 -2.013747 -0.377957 -0.393802 
    2 1.711172 -0.552468 1.018727 
2 0 0.155821 -0.222691 0.496586 
    1 0.563638 -0.756709 1.050212 
    2 -1.446159 -0.891549 0.256695 

我想洗牌此數據框對指數的第一級,所以可能的結果將是:

  A   B   C 
1 0 -1.081853 0.261876 -1.771075 
    1 -2.013747 -0.377957 -0.393802 
    2 1.711172 -0.552468 1.018727 
0 0 2.400417 0.698638 1.231540 
    1 -0.023154 -2.110450 0.774964 
    2 -1.282392 -0.062794 1.471655 
2 0 0.155821 -0.222691 0.496586 
    1 0.563638 -0.756709 1.050212 
    2 -1.446159 -0.891549 0.256695 

回答

4

reindex方法可以在傳遞符合所需順序的元組重新排序的數組時完成此操作。在哪一點,重新排序可以完成最適合您的問題。例如:

In [38]: df 
Out[38]: 
      A   B   C 
0 0 -1.725337 0.111493 0.178294 
    1 -1.809003 -0.614219 -0.931909 
    2 0.621427 -0.186233 0.254727 
1 0 -1.322863 1.242415 1.375579 
    1 0.249738 -1.280204 0.356491 
    2 -0.743671 0.325841 -0.167772 
2 0 -0.070937 0.401172 -1.790801 
    1 1.433794 2.257198 1.848435 
    2 -1.021557 -1.054363 -1.485536 

In [39]: neworder = [1, 0, 2] 

In [41]: newindex = sorted(df.index, key=lambda x: neworder.index(x[0])) 

In [42]: newindex 
Out[42]: 
[(1L, 0L), 
(1L, 1L), 
(1L, 2L), 
(0L, 0L), 
(0L, 1L), 
(0L, 2L), 
(2L, 0L), 
(2L, 1L), 
(2L, 2L)] 

In [43]: df.reindex(newindex) 
Out[43]: 
      A   B   C 
1 0 -1.322863 1.242415 1.375579 
    1 0.249738 -1.280204 0.356491 
    2 -0.743671 0.325841 -0.167772 
0 0 -1.725337 0.111493 0.178294 
    1 -1.809003 -0.614219 -0.931909 
    2 0.621427 -0.186233 0.254727 
2 0 -0.070937 0.401172 -1.790801 
    1 1.433794 2.257198 1.848435 
    2 -1.021557 -1.054363 -1.485536 
+0

這是一個非常簡潔的解決方案。我結束了矢量化的排序是這樣的:'newindex = df.index [np.argsort(neworder [df.index.labels [0])]' –

+0

榮譽的矢量化!你已經提高了我的Numpy-fu。有一點:因爲''np.sort'' /''np.argsort''默認情況下使用,這是不能保證穩定「快速排序」算法,它並不等同於使用Python的排序功能,這是保證穩定的。儘管在你的解決方案中排序可以使用參數''kind ='heapsort''來保持穩定。 – Garrett

+0

@Garrett由numpy文檔(v 1.7.1)''heapsort''是不穩定的。然而,「mergesort」被認爲是穩定的。你爲什麼推薦一個呢? –

0

這將是如果下面的工作更容易,but no

df.ix[[1, 0, 2]] 

以下是更多的解決方法。也許有更好的方法,但我無法弄清楚。這只是創建了以正確的順序DataFrame「片」的列表,並與​​連接它們。

In : df 
Out: 
      A   B   C 
0 0 1.202098 -0.031121 1.417629 
    1 -0.895862 0.697531 -0.572411 
    2 1.179101 -0.008602 1.583385 
1 0 1.969477 -0.968004 -0.567695 
    1 -1.504443 -0.002264 -0.413091 
    2 -1.412457 0.310518 0.267475 
2 0 -0.385933 -0.471800 -0.598141 
    1 -0.105032 0.443437 -0.615566 
    2 -1.035326 -0.282289 -0.042762 

In : shuffled = [2,0,1] 

In : df2 = pandas.concat([df.ix[i:i] for i in shuffled]) 

In : df2 
Out: 
      A   B   C 
2 0 -0.385933 -0.471800 -0.598141 
    1 -0.105032 0.443437 -0.615566 
    2 -1.035326 -0.282289 -0.042762 
0 0 1.202098 -0.031121 1.417629 
    1 -0.895862 0.697531 -0.572411 
    2 1.179101 -0.008602 1.583385 
1 0 1.969477 -0.968004 -0.567695 
    1 -1.504443 -0.002264 -0.413091 
    2 -1.412457 0.310518 0.267475 
+0

爲什麼這不是工作? IDX = IndexSlice df.loc [IDX [洗牌,:] – Dickster