所以我正在网上抓一些网站,我查看替换数据,我想同时知道得分。因此,我知道潜艇发生的时间和目标发生的时间。然后,我想要在替换的特定时间链接得分。这是一个例子:
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
答案 0 :(得分:1)
解决方案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
此备用解决方案假设您的分数是数据框,就像您在示例中创建的那样。但是,要使此解决方案起作用,您必须明确定义评分的时间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_y
(scores
的时间),分组{{ {1}},time_x
和in
,然后获取每个组的最后一条记录。
out
结果:
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_x
和in
的重复记录将被删除。如果需要,您可以删除out
和key
列。