在世界杯锦标赛组中产生配对

时间:2015-06-02 21:04:48

标签: python r pandas plyr split-apply-combine

我为2015 FIFA女足世界杯提供了一些数据:

import pandas as pd

df = pd.DataFrame({
    'team':['Germany','USA','France','Japan','Sweden','England','Brazil','Canada','Australia','Norway','Netherlands','Spain',
       'China','New Zealand','South Korea','Switzerland','Mexico','Colombia','Thailand','Nigeria','Ecuador','Ivory Coast','Cameroon','Costa Rica'],
    'group':['B','D','F','C','D','F','E','A','D','B','A','E','A','A','E','C','F','F','B','D','C','B','C','E'],
    'fifascore':[2168,2158,2103,2066,2008,2001,1984,1969,1968,1933,1919,1867,1847,1832,1830,1813,1748,1692,1651,1633,1485,1373,1455,1589],
    'ftescore':[95.6,95.4,92.4,92.7,91.6,89.6,92.2,90.1,88.7,88.7,86.2,84.7,85.2,82.5,84.3,83.7,81.1,78.0,68.0,85.7,63.3,75.6,79.3,72.8]
    })

df.groupby(['group', 'team']).mean()

output

现在,我想生成一个新的数据框,其中包含来自group的每个df中的6种可能的配对或匹配,格式如下:

group    team1        team2
A        Canada       China
A        Canada       Netherlands
A        Canada       New Zealand
A        China        Netherlands
A        China        New Zealand
A        Netherlands  New Zealand
B        Germany      Ivory Coast
B        Germany      Norway
...     

这样做简洁明了的方法是什么?我可以在每个groupteam中执行一系列循环,但我觉得应该使用pandassplit-apply-combine范例以更清晰的矢量化方式来执行此操作。

编辑:我也欢迎任何R答案,认为在这里比较R和Pandas的方式会很有趣。添加了r代码。

这是R形式的数据,如评论中所要求的那样:

team <- c('Germany','USA','France','Japan','Sweden','England','Brazil','Canada','Australia','Norway','Netherlands','Spain',
      'China','New Zealand','South Korea','Switzerland','Mexico','Colombia','Thailand','Nigeria','Ecuador','Ivory Coast','Cameroon','Costa Rica')
group <- c('B','D','F','C','D','F','E','A','D','B','A','E','A','A','E','C','F','F','B','D','C','B','C','E')
fifascore <- c(2168,2158,2103,2066,2008,2001,1984,1969,1968,1933,1919,1867,1847,1832,1830,1813,1748,1692,1651,1633,1485,1373,1455,1589)
ftescore <- c(95.6,95.4,92.4,92.7,91.6,89.6,92.2,90.1,88.7,88.7,86.2,84.7,85.2,82.5,84.3,83.7,81.1,78.0,68.0,85.7,63.3,75.6,79.3,72.8)

df <- data.frame(team, group, fifascore, ftescore)

2 个答案:

答案 0 :(得分:3)

这是两线解决方案:

import itertools

for grpname,grpteams in df.groupby('group')['team']:
    # No need to use grpteams.tolist() to convert from pandas Series to Python list
    print list(itertools.combinations(grpteams, 2))

[('Canada', 'Netherlands'), ('Canada', 'China'), ('Canada', 'New Zealand'), ('Netherlands', 'China'), ('Netherlands', 'New Zealand'), ('China', 'New Zealand')]
[('Germany', 'Norway'), ('Germany', 'Thailand'), ('Germany', 'Ivory Coast'), ('Norway', 'Thailand'), ('Norway', 'Ivory Coast'), ('Thailand', 'Ivory Coast')]
[('Japan', 'Switzerland'), ('Japan', 'Ecuador'), ('Japan', 'Cameroon'), ('Switzerland', 'Ecuador'), ('Switzerland', 'Cameroon'), ('Ecuador', 'Cameroon')]
[('USA', 'Sweden'), ('USA', 'Australia'), ('USA', 'Nigeria'), ('Sweden', 'Australia'), ('Sweden', 'Nigeria'), ('Australia', 'Nigeria')]
[('Brazil', 'Spain'), ('Brazil', 'South Korea'), ('Brazil', 'Costa Rica'), ('Spain', 'South Korea'), ('Spain', 'Costa Rica'), ('South Korea', 'Costa Rica')]
[('France', 'England'), ('France', 'Mexico'), ('France', 'Colombia'), ('England', 'Mexico'), ('England', 'Colombia'), ('Mexico', 'Colombia')]

说明:

首先,我们使用df.groupby('group')获取每个小组内的小组的团队列表,并对其进行迭代并访问其小组&#39;系列,获取每组中4支球队的名单:

for grpname,grpteams in df.groupby('group')['team']:
    teamlist = grpteams.tolist()
... 
['Canada', 'Netherlands', 'China', 'New Zealand']
['Germany', 'Norway', 'Thailand', 'Ivory Coast']
['Japan', 'Switzerland', 'Ecuador', 'Cameroon']
['USA', 'Sweden', 'Australia', 'Nigeria']
['Brazil', 'Spain', 'South Korea', 'Costa Rica']
['France', 'England', 'Mexico', 'Colombia']

然后我们生成所有队列的元组列表。 David Arenburg的帖子提醒我使用itertools.combinations(..., 2)。但我们可以使用生成器或嵌套for循环:

def all_play_all(teams):
  for team1 in teams:
    for team2 in teams:
      if team1 < team2: # [Note] We don't need to generate indices then index into teamlist, just use direct string comparison
        yield (team1,team2)

>>> [match for match in all_play_all(grpteams)]
[('France', 'Mexico'), ('England', 'France'), ('England', 'Mexico'), ('Colombia', 'France'), ('Colombia', 'England'), ('Colombia', 'Mexico')]

请注意,我们采用快捷方式首先生成所有可能的索引元组,然后使用这些索引编入团队列表:

>>> T = len(teamlist) + 1
>>> [(i,j) for i in range(T) for j in range(T) if i<j]
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]

(注意:如果我们使用直接比较团队名称的方法,它会产生轻微的副作用(按字母顺序)使用组名(它们最初是按播种顺序排序,而不是按字母顺序排序),所以例如&# 39;中国&#39;荷兰&#39;所以他们的配对将显示为(&#39;荷兰&#39;中国&#39;)而不是(&#39;中国和#39;,荷兰&#39;))

答案 1 :(得分:3)

使用R,这是一个可能的$sql = "SELECT * FROM orders"; $result = mysql_query($sql); if (!$result) { echo "Could not successfully run query ($sql) from DB: " . mysql_error(); exit; } if (mysql_num_rows($result) == 0) { echo "No rows found, nothing to print so am exiting"; exit; } session_id($id); session_start(); echo $_SESSION['user_name']; echo $row["product_order"]; 解决方案,使用它在GitHub上的devel版本

data.table