2017-07-26 73 views
0

因此,我正在網站上抓取一些網站,並查看替代數據,同時我想知道分數。所以我有當潛艇出現的時間和目標發生的時間。然後,我想要在替換的具體時間鏈接分數。這裏有一個例子:數據條件語句

import pandas as pd 
df_stack = ['31:12', 
    '34:12', 
    '34:12', 
    '57:50', 
    '57:50', 
    '67:03', 
    '68:48', 
    '77:18', 
    '80:00', 
    '90:00'] 

# This df_stack that is commented works. 
#df_stack = ['34:40', '36:53', '55:38', '56:03', '67:31', '74:43', '84:38', 
#  '86:58', '86:58'] 

In = ['a']*len(df_stack) 
Out = ['b']*len(df_stack) 
Subs = pd.DataFrame(data = [In,Out]).T 
Subs.columns = ['In','Out'] 
Subs.index = [df_stack] 


### This score works 

#Score = ['0-0','0-1','1-1'] 
#Score = pd.DataFrame(data = [Score]).T 
#Score.columns = ['Score'] 
#Score.index = ['61:37','61:38','81:45'] 

### This Score Doesn't Work 
Score = ['0-0','0-1','1-1','2-1'] 
Score = pd.DataFrame(data = [Score]).T 
Score.columns = ['Score'] 
Score.index = ['58:39', '58:40', '83:31', '89:41'] 


k = 0 
j = 0 
q = 0 

overall_score = [] 
time = [] 
for i in Subs.index.tolist(): 
     try: 
      if i < Score.index.tolist()[k]: 
       overall_score.append(Score['Score'][k]) 
       time.append([Score.index[k],i,k,'top',Score['Score'][k]]) 
       q += 1 
      else: 


       if (k > 0 and i > Score.index.tolist()[k] and i < Score.index.tolist()[k+1]): 
        overall_score.append(Score['Score'][k]) 
        time.append([Score.index[k],i,Score.index[k+1],k,'No Change',q,Score['Score'][k]]) 
        j += 1 
        q += 1 

       if (k == 0 and i > Score.index.tolist()[k]): 
        k += 1 
        q += 1 

        overall_score.append(Score['Score'][k]) 
        time.append([Score.index[k],i,Score.index[k+1],k,'First Goal',Score['Score'][k]]) 

       if (j >= 1 and i > Score.index.tolist()[k+j]): 
        h = 0 
        h += k + j 
        if k >= len(Score): 
         h = len(Score)-1 
        overall_score.append(Score['Score'][h]) 
        time.append([Score.index[h],i,k,'Another Goal',j,Score['Score'][k]]) 


     except IndexError: 
      #overall_score.append(Score['Score'][k-1]) 
      overall_score.append(Score['Score'][len(Score)-1]) 

我知道這是一個很大的代碼,但overall_score的期望輸出應該是:

['0-0', '0-0', '0-0', '0-0', '0-0', '0-1', '0-1', '0-1','0-1' '2-1'] 

有可能做到這一點更簡單的方法,我也願意把整個刮碼在線,但它相當長。因此,與總分的替代會是什麼樣子:

 In Out Score 
31:12 a b 0-0 
34:12 a b 0-0 
34:12 a b 0-0 
57:50 a b 0-0 
57:50 a b 0-0 
67:03 a b 0-1 
68:48 a b 0-1 
77:18 a b 0-1 
80:00 a b 0-1 
90:00 a b 2-1 

回答

1

SOLUTION 1

一種解決方案是使用你的數據框的apply方法,因爲你有一個正確的條件邏輯適用於功能你的行。

該解決方案使用分數字典,其中關鍵是時間,值是分數。字典然後作爲附加參數傳遞給函數,該函數將邏輯應用於您的數據框。

我重新創建下面的數據,但使用的時間作爲指標,我創建了一個實際time柱:

df_stack = ['31:12', '34:12', '34:12', '57:50', '57:50', '67:03', '68:48', '77:18', '80:00', '90:00'] 
subs = pd.DataFrame({'time': df_stack}) 
subs['in'] = 'a' 
subs['out'] = 'b' 

現在,這裏的scores詞典:

scores = {'58:39': '0-0', '58:40': '0-1', '83:31': '1-1', '89:41': '2-1'} 

現在這是您將傳遞給apply的功能。請注意,此函數在迭代值之前按鍵對字典進行排序以確定正確的分數。該函數還假定所有分數都以「0-0」開始。您還可以通過添加'00:00': '0-0'的鍵/值記錄,在字典中明確定義此假設。現在

def map_score_to_time(time, scores): 
    score_at_sub = '0-0' 
    for score_time, score in sorted(scores.items(), key=lambda kv: kv[0]): 
     if time >= score_time: 
      score_at_sub = score 
    return score_at_sub 

,與你的函數定義的,你現在可以應用到您的數據幀:

subs['score'] = subs['time'].apply(map_score_to_time, scores=scores) 

結果:

time in out score 
0 31:12 a b 0-0 
1 34:12 a b 0-0 
2 34:12 a b 0-0 
3 57:50 a b 0-0 
4 57:50 a b 0-0 
5 67:03 a b 0-1 
6 68:48 a b 0-1 
7 77:18 a b 0-1 
8 80:00 a b 0-1 
9 90:00 a b 2-1 

解決方案2

此備用解決方案假定你的分數是一個數據框,就像你擁有的那樣e在你的例子中創建。但是,要使此解決方案有效,您必須明確定義00:00時刻的分數。假設遊戲的得分始終爲0-0,時間爲00:00

我們的subs數據幀仍將與之前的相同,因此我們來構建我們的scores_df數據幀。請注意,我明確向數據框添加了一條記錄,以獲得時間爲00:00的記錄。

scores_df = pd.DataFrame({'time': ['00:00', '58:39', '58:40', '83:31', '89:41'], 'score': ['0-0', '0-0', '0-1', '1-1', '2-1']}) 

現在,我們必須在兩個數據框之間進行笛卡爾連接。這是一箇中間步驟,這樣我們就可以得到subs的時間列和scores的時間列。爲了進行這種連接,我們必須創建一個虛擬連接鍵,因此您需要爲兩個數據幀創建連接鍵。

# Create dummy keys 
scores_df['key'] = 1 
subs['key'] = 1 

# Now join 
merged_df = subs.merge(scores_df, how='inner', on='key') 

後加入,要篩選出記錄,其中time_x(從subs的時間)大於time_yout(在從scores時間),通過time_xin組,和,然後抓住最後一個記錄每組。

final_df = merged_df[merged_df['time_x'] > merged_df['time_y']].groupby(['time_x', 'in', 'out']).tail(1) 

結果:

time_x in out key score time_y 
0 31:12 a b 1 0-0 00:00 
10 34:12 a b 1 0-0 00:00 
20 57:50 a b 1 0-0 00:00 
27 67:03 a b 1 0-1 58:40 
32 68:48 a b 1 0-1 58:40 
37 77:18 a b 1 0-1 58:40 
42 80:00 a b 1 0-1 58:40 
49 90:00 a b 1 2-1 89:41 

注意通過time_xin,並out重複的記錄被丟棄。如果需要,您可以刪除keytime_y列。

+0

我與解決方案1去了。我從來沒有想過創建一本字典,但它完美的作品。 –

+0

我改變了解決方案的唯一一件事是我在函數條件語句中添加了時間> score_time或time == score_time。 –

+1

@AdamWarner好的!你可以把它捲入'time> = score_time' :) –