2017-06-04 69 views
0

我想將列添加到Python中的數據幀/大熊貓如下:分組,並在大熊貓數據幀編號項目

| MarketID | SelectionID | Time | SelectNumber | 

| 112337406 | 3819251.0 | 13:38:32 |   4 | 

| 112337406 | 3819251.0 | 13:39:03 |   4 | 

| 112337406 | 4979206.0 | 11:29:34 |   1 | 

| 112337406 | 4979206.0 | 11:37:34 |   1 | 

| 112337406 | 5117439.0 | 13:36:32 |   3 | 

| 112337406 | 5117439.0 | 13:37:03 |   3 | 

| 112337406 | 5696467.0 | 13:23:03 |   2 | 

| 112337406 | 5696467.0 | 13:23:33 |   2 | 

| 112337407 | 3819254.0 | 13:39:12 |   4 | 

| 112337407 | 4979206.0 | 11:29:56 |   1 | 

| 112337407 | 4979206.0 | 16:27:34 |   1 | 

| 112337407 | 5117441.0 | 13:36:54 |   3 | 

| 112337407 | 5117441.0 | 17:47:11 |   3 | 

| 112337407 | 5696485.0 | 13:23:04 |   2 | 

| 112337407 | 5696485.0 | 18:23:59 |   2 | 

我目前擁有的市場ID,選擇ID和時間,我想生成SelectNumber列,它表示特定的選擇標識出現在特定的MarketID內的時間順序。一旦編號,該MarketID中相同選擇ID的所有其他迭代都需要編號相同。 MarketID將始終是唯一的,但同一個selectionID可以出現在多於一個MarketID中。

這讓我難住,有什麼想法嗎?

+0

首先,你嘗試過什麼? –

+0

我嘗試了以下方法,但它只對SelectionID df ['SelectNo'] = df.sort_values('Suggest Time')。groupby(['BF_MarketID','BF_SelectionID'],sort = False).cumcount ()+1 – RicHep365

回答

0

首先,您需要出現的順序是'MarketID'和'SelectionID'的組合,所以讓我們分類時間。 然後,對於每個'MarketID'獲取唯一的'SelectionID'並按發生順序對它們進行編號(已經排序,因爲df是按列時間排序的)。其次,將數字'MarketID'和'SelectionID'與訂單一起用於後面的設置。

我給你兩個解決方案的第一部分:

dfnewindex = df.sort_values('Time').set_index('MarketID') 
valuesetter = {} 
for indx in dfnewindex.index.unique(): 
    selectionid_per_marketid = dfnewindex.loc[indx].sort_values('Time')['SelectionID'].drop_duplicates().values 
    valuesetter.update(dict(zip(zip(len(selectionid_per_marketid)*[indx], selectionid_per_marketid), range(1, 1+len(selectionid_per_marketid))))) 

100圈,最好的3:每圈3.22毫秒

df_sorted = df.sort_values('Time') 
valuesetter = {} 
for mrktid in df_sorted['MarketID'].unique(): 
    sltnids = df_sorted[df_sorted['MarketID']==mrktid]['SelectionID'].drop_duplicates(keep='first').values 
    valuesetter.update(dict(zip(zip(len(sltnids)*[mrktid], sltnids), range(1, 1+len(sltnids))))) 

100圈,最好的3:2.59毫秒每個環路

布爾切片溶液稍快在這種情況下

輸出:

valuesetter 

{(112337406, 3819251.0): 4, 
(112337406, 4979206.0): 1, 
(112337406, 5117439.0): 3, 
(112337406, 5696467.0): 2, 
(112337407, 3819254.0): 4, 
(112337407, 4979206.0): 1, 
(112337407, 5117441.0): 3, 
(112337407, 5696485.0): 2} 

對於第二部分,該字典用於生成列,即SelectNumber。再次兩種溶液,第一個使用多指標,第二GROUPBY:

map(lambda x: valuesetter[x], df.set_index(['MarketID', 'SelectionID']).index.values) 

1000個循環,最好的3:每次循環1.23毫秒

map(lambda x: valuesetter[x], df.groupby(['MarketID', 'SelectionID']).count().index.values) 

1000個循環,最好的3:每次循環

1.59毫秒

multiindex似乎是最快的解決方案。

最後,到現在爲止,最快的答案:

df_sorted = df.sort_values('Time') 
valuesetter2 = {} 
for mrktid in df_sorted['MarketID'].unique(): 
    sltnids = df_sorted[df_sorted['MarketID']==mrktid]['SelectionID'].drop_duplicates(keep='first').values 
    valuesetter2.update(dict(zip(zip(len(sltnids)*[mrktid], sltnids), range(1, 1+len(sltnids))))) 
df_sorted['SelectNumber'] = list(map(lambda x: valuesetter[x], df.set_index(['MarketID', 'SelectionID']).index.values)) 
+0

謝謝大安,我會試試這個 – RicHep365

+0

嘿大安,第一個解決方案是懸掛,有幾百萬行,但我不會指望它會持續多久。它卡在for循環 – RicHep365

+0

好點,忘了檢查時間。我已經把最快的解決方案放在了最前面。 – Daan