反透视包含一行中两个团队信息的数据框?
Unpivot a data-frame that has information of two teams in one row?
我有一些数据包含两个对立球队的信息
home_x away_x
0 7 28
1 11 10
2 11 20
3 12 15
4 12 16
我知道 .melt(),returns 是这样的:
variable value
0 home_x 7
1 home_x 11
2 home_x 11
3 home_x 12
4 home_x 12
所以这里每个值都是一行。
每个团队都有几个属性。
我希望每一行都包含相应球队(主场或客场)的所有属性
最终目标是让两队的所有属性都排在同一行。这将使行数加倍。
home_x away_x
0 7 28
将转化为:
team1_x team2_x
0 7 28
0 28 7
这里有一个方法:
您可能需要对列名称的最后一个拆分进行分组,然后在轴 = 1 上进行分组,然后遍历这些组并反转列顺序并将它们命名为相同的后缀:
def myinfo(data):
c = data.columns.str.split("_").str[-1]
f = lambda x: pd.DataFrame.set_axis(x, ["team1","team2"],axis=1)
l = [pd.concat([*map(f , (v,v.iloc[:,::-1]))]).add_suffix(f"_{k}")
for k,v in data.groupby(c,axis=1)]
return pd.concat(l,axis=1).sort_index()
print(myinfo(df))
team1_x team2_x
0 7 28
0 28 7
1 11 10
1 10 11
2 11 20
2 20 11
3 12 15
3 15 12
4 12 16
4 16 12
样本 df:
home_x
away_x
home_y
away_y
0
7
28
7
20
1
28
7
28
13
2
28
7
28
4
3
7
28
7
58
4
11
10
11
10
尝试:
res = pd.DataFrame()
for c in df.columns.str.split("_").str[1].unique():
p1 = df.filter(regex=f"{c}$")
c1,c2 =p1.columns
df_map = {c1:c2, c2:c1}
swap = p1.rename(columns={**df_map})
res = pd.concat([res,p1.append(swap).sort_index(ignore_index=True)], axis=1)
然后重命名列。
import re
repl = {'home': 'team1', 'away': 'team2'}
res.columns = [re.sub('|'.join(repl.keys()), lambda x: repl[x.group()], i) for i in res.columns]
team1_x
team2_x
team1_y
team2_y
0
7
28
7
20
1
28
7
20
7
2
28
7
28
13
3
7
28
13
28
4
28
7
28
4
5
7
28
4
28
6
7
28
7
58
7
28
7
58
7
8
11
10
11
10
9
10
11
10
11
我有一些数据包含两个对立球队的信息
home_x away_x
0 7 28
1 11 10
2 11 20
3 12 15
4 12 16
我知道 .melt(),returns 是这样的:
variable value
0 home_x 7
1 home_x 11
2 home_x 11
3 home_x 12
4 home_x 12
所以这里每个值都是一行。
每个团队都有几个属性。
我希望每一行都包含相应球队(主场或客场)的所有属性
最终目标是让两队的所有属性都排在同一行。这将使行数加倍。
home_x away_x
0 7 28
将转化为:
team1_x team2_x
0 7 28
0 28 7
这里有一个方法:
您可能需要对列名称的最后一个拆分进行分组,然后在轴 = 1 上进行分组,然后遍历这些组并反转列顺序并将它们命名为相同的后缀:
def myinfo(data):
c = data.columns.str.split("_").str[-1]
f = lambda x: pd.DataFrame.set_axis(x, ["team1","team2"],axis=1)
l = [pd.concat([*map(f , (v,v.iloc[:,::-1]))]).add_suffix(f"_{k}")
for k,v in data.groupby(c,axis=1)]
return pd.concat(l,axis=1).sort_index()
print(myinfo(df))
team1_x team2_x
0 7 28
0 28 7
1 11 10
1 10 11
2 11 20
2 20 11
3 12 15
3 15 12
4 12 16
4 16 12
样本 df:
home_x | away_x | home_y | away_y | |
---|---|---|---|---|
0 | 7 | 28 | 7 | 20 |
1 | 28 | 7 | 28 | 13 |
2 | 28 | 7 | 28 | 4 |
3 | 7 | 28 | 7 | 58 |
4 | 11 | 10 | 11 | 10 |
尝试:
res = pd.DataFrame()
for c in df.columns.str.split("_").str[1].unique():
p1 = df.filter(regex=f"{c}$")
c1,c2 =p1.columns
df_map = {c1:c2, c2:c1}
swap = p1.rename(columns={**df_map})
res = pd.concat([res,p1.append(swap).sort_index(ignore_index=True)], axis=1)
然后重命名列。
import re
repl = {'home': 'team1', 'away': 'team2'}
res.columns = [re.sub('|'.join(repl.keys()), lambda x: repl[x.group()], i) for i in res.columns]
team1_x | team2_x | team1_y | team2_y | |
---|---|---|---|---|
0 | 7 | 28 | 7 | 20 |
1 | 28 | 7 | 20 | 7 |
2 | 28 | 7 | 28 | 13 |
3 | 7 | 28 | 13 | 28 |
4 | 28 | 7 | 28 | 4 |
5 | 7 | 28 | 4 | 28 |
6 | 7 | 28 | 7 | 58 |
7 | 28 | 7 | 58 | 7 |
8 | 11 | 10 | 11 | 10 |
9 | 10 | 11 | 10 | 11 |