Python 数据条件语句

Python 数据条件语句,python,pandas,Python,Pandas,所以我在网上搜刮一些网站,查看替换数据,同时我想知道得分。所以我有替补上场的时间和进球的时间。然后我想把具体的换人时间的得分联系起来。以下是一个例子: 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'] # Thi

所以我在网上搜刮一些网站,查看替换数据,同时我想知道得分。所以我有替补上场的时间和进球的时间。然后我想把具体的换人时间的得分联系起来。以下是一个例子:

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])
也许有一种更简单的方法可以做到这一点,我也愿意把整个代码放到网上,但它相当长。因此,用总分进行替换的情况如下所示:

      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

一种解决方案是在数据帧上使用该方法,前提是您有一个将正确的条件逻辑应用于行的函数

此解决方案使用分数字典,其中键是时间,值是分数。然后将字典作为附加参数传递给将逻辑应用于数据帧的函数

我在下面重新创建了您的数据,但没有使用时间作为索引,而是创建了一个实际的
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 = {'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
   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
解决方案2

此替代解决方案假设您的分数是一个数据帧,就像您在示例中创建的那样。但是,要使此解决方案起作用,您必须明确定义时间
00:00
的分数。让我们假设一场比赛的分数在时间
00:00
时总是
0-0

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\u 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\ux
(来自
subs
的时间)大于
time\y
(来自
分数的时间
)的记录,按
time\ux
分组,然后抓取每组的最后一条记录

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

    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
   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\u x
in
out
的重复记录将被删除。如果需要,可以删除
时间
列。

我选择了解决方案1。我从来没有想过要创建一个字典,但它工作得很好。我为解决方案一所做的唯一改变是在函数条件语句中添加了time>score\u time或time==score\u time。@AdamWarner很好!你可以把它汇总到
time>=score\u time
:)@AdamWarner我还修改了我的答案以反映
=
。此外,我在回答中还犯了一个错误,即按
kv[1]
对词典进行排序。为了按键排序,实际上是
kv[0]