删除列名的后缀和 unpivot
Remove suffix of the column names and unpivot
我想用列名“Year”、“Item”和“$”对以下 table 进行逆透视。我的解决方法是将 table 分成两个数据框并删除后缀,然后垂直连接两列。还有其他更简单的方法可以解决这个问题吗?
示例数据框:
data = {'Year_x': [1993, 1994, 1995, 1996],
'Year_y': [2000, 2001, 2002, 2003],
'Item_x':['A','B','C','D'],
'Item_y':['E','F','G','H'],
'$':[3,4,5,6]}
pd.DataFrame.from_dict(data)
Year_x
Year_y
Item_x
Item_y
$
1993
2000
一个
E
3
1994
2001
B
F
4
1995
2002
C
G
5
1996
2003
D
H
6
我想达到的目标:
年
项目
$
1993
一个
3
1994
B
4
1995
C
5
1995
D
6
2000
E
3
2001
F
4
2002
G
5
2003
H
6
使用DataFrame.set_index
将没有分隔符_
的列转换为索引,然后将列名拆分为MultiIndex
:
cols = ['$']
#if multiple columns
cols = ['$', '$Column1', '$Column2']
df1 = df.set_index(cols)
df1.columns = df1.columns.str.split('_', expand=True)
df1 = (df1.stack()
.sort_values(['Item','Year'])
.reset_index()[['Year','Item'] + cols])
print (df1)
Year Item $
0 1993 A 3
1 1994 B 4
2 1995 C 5
3 1996 D 6
4 2000 E 3
5 2001 F 4
6 2002 G 5
7 2003 H 6
与列表理解的连接
>>> pd.concat([df[["Year_" + c, "Item_" + c, "$"]].rename({"Year_" + c : "Year", "Item_" + c : "Item"}, axis=1) for c in ("x", "y")]).reset_index(drop=True)
Year Item $
0 1993 A 3
1 1994 B 4
2 1995 C 5
3 1996 D 6
4 2000 E 3
5 2001 F 4
6 2002 G 5
7 2003 H 6
或者,通过 pd.wide_to_long(...)
>>> pd.wide_to_long(df, ["Year", "Item"], i=["$"], j="Var", sep="_", suffix="\w+").reset_index()
$ Var Year Item
0 3 x 1993 A
1 4 x 1994 B
2 5 x 1995 C
3 6 x 1996 D
4 3 y 2000 E
5 4 y 2001 F
6 5 y 2002 G
7 6 y 2003 H
- 第一步,找到列的后缀
df_col = pd.DataFrame(df.columns.str.split('_').tolist())
df_col['col'] = df.columns.tolist()
print(df_col)
# 0 1 col
# 0 Year x Year_x
# 1 Year y Year_y
# 2 Item x Item_x
# 3 Item y Item_y
# 4 $ None $
- step2,处理输出列
cond = df_col[1].isnull()
cols_without_subfix = df_col.loc[cond, 'col'].tolist()
obj = df_col[~cond].groupby(1)['col'].agg(list)
obj = obj.map(lambda x: x + cols_without_subfix)
print(obj)
# 1
# x [Year_x, Item_x, $]
# y [Year_y, Item_y, $]
# Name: col, dtype: object
- 第 3 步,迭代输出列并连接它们。
df_list = []
for i in obj:
dfn = df[i]
dfn.columns = dfn.columns.str.split('_').str[0]
df_list.append(dfn)
df_output = pd.concat(df_list)
print(df_output)
# Year Item $
# 0 1993 A 3
# 1 1994 B 4
# 2 1995 C 5
# 3 1996 D 6
# 0 2000 E 3
# 1 2001 F 4
# 2 2002 G 5
# 3 2003 H 6
我想用列名“Year”、“Item”和“$”对以下 table 进行逆透视。我的解决方法是将 table 分成两个数据框并删除后缀,然后垂直连接两列。还有其他更简单的方法可以解决这个问题吗?
示例数据框:
data = {'Year_x': [1993, 1994, 1995, 1996],
'Year_y': [2000, 2001, 2002, 2003],
'Item_x':['A','B','C','D'],
'Item_y':['E','F','G','H'],
'$':[3,4,5,6]}
pd.DataFrame.from_dict(data)
Year_x | Year_y | Item_x | Item_y | $ |
---|---|---|---|---|
1993 | 2000 | 一个 | E | 3 |
1994 | 2001 | B | F | 4 |
1995 | 2002 | C | G | 5 |
1996 | 2003 | D | H | 6 |
我想达到的目标:
年 | 项目 | $ |
---|---|---|
1993 | 一个 | 3 |
1994 | B | 4 |
1995 | C | 5 |
1995 | D | 6 |
2000 | E | 3 |
2001 | F | 4 |
2002 | G | 5 |
2003 | H | 6 |
使用DataFrame.set_index
将没有分隔符_
的列转换为索引,然后将列名拆分为MultiIndex
:
cols = ['$']
#if multiple columns
cols = ['$', '$Column1', '$Column2']
df1 = df.set_index(cols)
df1.columns = df1.columns.str.split('_', expand=True)
df1 = (df1.stack()
.sort_values(['Item','Year'])
.reset_index()[['Year','Item'] + cols])
print (df1)
Year Item $
0 1993 A 3
1 1994 B 4
2 1995 C 5
3 1996 D 6
4 2000 E 3
5 2001 F 4
6 2002 G 5
7 2003 H 6
与列表理解的连接
>>> pd.concat([df[["Year_" + c, "Item_" + c, "$"]].rename({"Year_" + c : "Year", "Item_" + c : "Item"}, axis=1) for c in ("x", "y")]).reset_index(drop=True)
Year Item $
0 1993 A 3
1 1994 B 4
2 1995 C 5
3 1996 D 6
4 2000 E 3
5 2001 F 4
6 2002 G 5
7 2003 H 6
或者,通过 pd.wide_to_long(...)
>>> pd.wide_to_long(df, ["Year", "Item"], i=["$"], j="Var", sep="_", suffix="\w+").reset_index()
$ Var Year Item
0 3 x 1993 A
1 4 x 1994 B
2 5 x 1995 C
3 6 x 1996 D
4 3 y 2000 E
5 4 y 2001 F
6 5 y 2002 G
7 6 y 2003 H
- 第一步,找到列的后缀
df_col = pd.DataFrame(df.columns.str.split('_').tolist())
df_col['col'] = df.columns.tolist()
print(df_col)
# 0 1 col
# 0 Year x Year_x
# 1 Year y Year_y
# 2 Item x Item_x
# 3 Item y Item_y
# 4 $ None $
- step2,处理输出列
cond = df_col[1].isnull()
cols_without_subfix = df_col.loc[cond, 'col'].tolist()
obj = df_col[~cond].groupby(1)['col'].agg(list)
obj = obj.map(lambda x: x + cols_without_subfix)
print(obj)
# 1
# x [Year_x, Item_x, $]
# y [Year_y, Item_y, $]
# Name: col, dtype: object
- 第 3 步,迭代输出列并连接它们。
df_list = []
for i in obj:
dfn = df[i]
dfn.columns = dfn.columns.str.split('_').str[0]
df_list.append(dfn)
df_output = pd.concat(df_list)
print(df_output)
# Year Item $
# 0 1993 A 3
# 1 1994 B 4
# 2 1995 C 5
# 3 1996 D 6
# 0 2000 E 3
# 1 2001 F 4
# 2 2002 G 5
# 3 2003 H 6