2015-10-06 75 views
1

我有一個超市的銷售信息的數據框。數據框中的每一行代表一個項目,其中有幾個特徵作爲列。原來的數據幀是這樣的:熊貓樞軸或groupby動態生成的列

In [1]: import pandas as pd 
     my_data = [{'ticket_number' : '001', 'item' : 'tomato', 'ticket_price' : '21'}, 
       {'ticket_number' : '001', 'item' : 'candy', 'ticket_price' : '21'}, 
       {'ticket_number' : '001', 'item' : 'soup', 'ticket_price' : '21'}, 
       {'ticket_number' : '002', 'item' : 'soup', 'ticket_price' : '12'}, 
       {'ticket_number' : '002', 'item' : 'cola', 'ticket_price' : '12'}, 
       {'ticket_number' : '003', 'item' : 'beef', 'ticket_price' : '56'}, 
       {'ticket_number' : '003', 'item' : 'tomato', 'ticket_price' : '56'}, 
       {'ticket_number' : '003', 'item' : 'pork', 'ticket_price' : '56'}] 
     df = pd.DataFrame(my_data) 

In [2]: df 
Out [2]:  
      ticket_number ticket_price  item 
     0  001   21   tomato 
     1  001   21   candy 
     2  001   21   soup 
     3  002   12   soup 
     4  002   12   cola 
     5  003   56   beef 
     6  003   56   tomato 
     7  003   56   pork 

我需要一個數據幀,每一行代表與購買的全部商品和門票價格爲列票。在這個例子中:

  ticket_number ticket_price  item1 item2 item3 
     0  001   21   tomato candy soup 
     1  002   12   soup cola 
     2  003   56   beef tomato pork 

我試着用df.groupby(ticket_number).item.value_counts(),但這並不能創建新列。我從來沒有使用pivot_table,也許它很有用。

任何幫助將不勝感激。

謝謝!

+0

爲**轉換(您的數據幀)從廣角形式長篇**這是已知的。使用這些關鍵字將會獲得比當前標題更好的答案。 – smci

+0

它甚至不僅僅是一個數據透視表,因爲你並沒有將計數(特別是多個條目,例如多個'糖果')聚合到最終的計數表中,即'糖果','可樂'的單獨列。 ..你想要項目未排序(即按發生或購買的順序),或排序(例如按字母順序?) – smci

回答

4

使用GROUPBY做出那麼可以變成列也列出一個可能的方式:

In [24]: res = df.groupby(['ticket_number', 'ticket_price'])['item'].apply(list).apply(pd.Series) 

In [25]: res 
Out[25]: 
           0  1  2 
ticket_number ticket_price 
001   21   tomato candy soup 
002   12    soup cola NaN 
003   56    beef tomato pork 

然後,清理這一結果後位:

In [27]: res.columns = ['item' + str(i + 1) for i in res.columns] 

In [29]: res.reset_index() 
Out[29]: 
    ticket_number ticket_price item1 item2 item3 
0   001   21 tomato candy soup 
1   002   12 soup cola NaN 
2   003   56 beef tomato pork 

另一個可能的方法來創建一個新的列,其中每個組的項目編號爲groupby.cumcount

In [38]: df['item_number'] = df.groupby('ticket_number').cumcount() 

In [39]: df 
Out[39]: 
    item ticket_number ticket_price item_number 
0 tomato   001   21   0 
1 candy   001   21   1 
2 soup   001   21   2 
3 soup   002   12   0 
4 cola   002   12   1 
5 beef   003   56   0 
6 tomato   003   56   1 
7 pork   003   56   2 

,然後做一些整形:

In [40]: df.set_index(['ticket_number', 'ticket_price', 'item_number']).unstack(-1) 
Out[40]: 
           item 
item_number      0  1  2 
ticket_number ticket_price 
001   21   tomato candy soup 
002   12    soup cola NaN 
003   56    beef tomato pork 

從這裏,與列名的一些清潔,可以實現與上述相同。

與​​和untack的成形步驟也可以與pivot_table來完成:df.pivot_table(columns=['item_number'], index=['ticket_number', 'ticket _price'], values='item', aggfunc='first')