2017-02-13 16 views
3

假設我有一個這樣的數據幀:GROUPBY和重塑長到寬屏格式的數據幀,同時聚集元素陣列

user order value 
0  1  0  90 
1  1  10  80 
2  1  20  70 
3  2  30  60 
4  2  40  50 
5  2  50  40 
6  3  60  30 
7  3  70  20 
8  3  80  10 

現在我想重新塑造它像這樣,每一個用戶得到自己的行與價值觀。請注意,該行根據數據框中order列中的值進行排序。

  1 2 3 ... 
user 
1  90 80 70 
2  60 50 40 
3  30 20 10 

甚至保持order任何原數據幀的另一個值,使每個組件是一個數組:

  1   2   3 ... 
user 
1  [0, 90] [10, 80] [20, 70] 
2  [30, 60] [40, 50] [50, 40] 
3  [60, 30] [70, 20] [80, 10] 

這是什麼操作調用,它有可能在幾行做代碼在熊貓?

回答

1

您可以在用戶上執行groupby,並根據其中包含的值對其進行累計計數。爲獲得的結果添加一個,這樣頭部就可以這樣格式化(即 - 1,2,3 ......等等)。

設置用戶和上述獲得的結果作爲索引stackDF以產生多索引系列。 Groupby在多索引系列對象的level=[0,1]上,並使用apply強制該系列採用數組值。最後,unstack框架來獲得所需的結果。

cc = df.groupby('user').cumcount() + 1 
df.set_index(['user', cc]).stack().groupby(level=[0,1]).apply(np.array).unstack() 
# alternatively - a DF level syntax by avoiding the `stack` call 
# df.set_index(['user', cc]).groupby(level=[0,1]).apply(lambda x: x.values.ravel()).unstack() 

enter image description here


要回到你的第一個期望的結果:

df.set_index(['user', cc])['value'].unstack() 

enter image description here

2

第一輸出

可以使用groupbylambda函數,其中numpy arraySeries.values創建:`:

df = df.groupby('user')['value'].apply(lambda x: pd.Series(x.values)).unstack() 
df.columns = df.columns + 1 
print (df) 
     1 2 3 
user    
1  90 80 70 
2  60 50 40 
3  30 20 10 

第二輸出

可以使用groupbylambda函數,其中通過DataFrame.values,其被轉換爲創建numpy arraylist,最後到Series

#for add 1 tp column names use rename 
df = df.groupby('user') 
     .apply(lambda x: pd.Series(x[['order','value']].values.tolist()) 
     .rename(index=lambda x: x+1)) 
print (df) 
      1   2   3 
user        
1  [0, 90] [10, 80] [20, 70] 
2  [30, 60] [40, 50] [50, 40] 
3  [60, 30] [70, 20] [80, 10] 

df = df.groupby('user').apply(lambda x: pd.Series(x[['order','value']].values.tolist())) 
#add 1 to column names last 
df.columns = df.columns + 1 
print (df) 
      1   2   3 
user        
1  [0, 90] [10, 80] [20, 70] 
2  [30, 60] [40, 50] [50, 40] 
3  [60, 30] [70, 20] [80, 10] 
0

如果您正在尋找在第一格式回答:

X = pd.DataFrame(data=[ 
     [1, 0, 90], 
     [1, 10, 80], 
     [1, 20, 70], 
     [2, 30, 60], 
     [2, 40, 50], 
     [2, 50, 40], 
     [3, 60, 30], 
     [3, 70, 20], 
     [3, 80, 10] 
    ], columns=['user', 'order', 'value']) 

# do ordering by groups: 
groups = X.groupby('user').apply(lambda x: x.sort_values('order').value.values) 

# recreate the DF. 
X_prime = pd.DataFrame(data=[i.astype(np.int) for i in groups.values], 
         index=groups.index) 

這產生了:

>>> X_prime 
     0 1 2 
user 
1  90 80 70 
2  60 50 40 
3  30 20 10