如何将行转换为列,但仅限于 python 中的 table 的一部分?
How to convert rows into columns but only for part of a table in python?
我有一个 table 与下面的简化示例具有相同的结构:
我想将第 1 列和第 2 列转换为 headers 列,并在 C1 值和 C2 值中找到列中的值。 table 的其余部分需要保持不变。我希望结果如下所示:
我找到了一种使用 pd.pivot table 的方法,如下所示,但我有十个 table 列要转换,所以我想一次性完成而不是像下面那样,这意味着我必须 运行 同一行十次,每次都会产生一个新的单独的 table 然后我必须将其合并到之前的输出中。这可能吗,我尝试在 pd.pivot_table 的列和值中使用一个列表,但它不能正常工作,因为它试图组合我给列表的列,而不是仅仅转置它们。有没有一种方法可以按照我在使用 pivot table 时一次性描述的方式转置 table 的一部分,或者是否有其他方法可以让我做到这一点?
TABLE1=pd.DataFrame({'Name':['John','Niomi','Jack','William','Bob','Stephanie'],
'Date Added':['05/05/2020','05/05/2020','03/04/2020','01/03/2020','10/04/2020','10/04/2020'],
'Column 1':['A','B','C','C','A','B'],
'C1 Value':['1','2','2','3','5','1'],
'Column 2':['D','D','G','F','G','F'],
'C2 Value':['5','7','9','5','2','1'],
'Column 3':['VALUE1','VALUE2','VALUE3','VALUE4','VALUE5','VALUE6'],
'Column 4':['VALUE7','VALUE8','VALUE9','VALUE10','VALUE11','VALUE12']})
table2=pd.pivot_table(TABLE1,index=('Name','Date Added'),columns='Column1',values='C1 Value',aggfunc='max',fill_value=0)
table3=pd.pivot_table(TABLE1,index=('Name','Date Added'),columns='Column2',values='C2 Value',aggfunc='max',fill_value=0)
table1.merge(table2,on=['Name','Date Added'])
这里的假设是 table 具有完全相同的列,因此您可以将其变形为一个函数并应用于每个函数:另外,速度大约是您使用枢轴 table.
def reshape(df):
#get various variables that will be reused
other = ['Name','Date Added','Column 3','Column 4']
#contain column 1 and c1 value
var1 = df.columns[df.columns.str.contains('1')].tolist()
#contain column 2 and c2 value
var2 = df.columns[df.columns.str.contains('2')].tolist()
#we'll use this to replace column 1,2 and c1,2
#allows us to merge them
repl = ['header','vals']
#set indices on both var1 and 2, and concat
res = (pd.concat([df.set_index(var1).rename_axis(index=repl).filter(other),
df.set_index(var2).rename_axis(index=repl).filter(other)]
)
#add the remaining indices
.set_index(other,append=True)
#pull out the values
.reset_index(1)
#unstack the header column and fill nulls
.unstack(0,fill_value=0)
)
return res
df.pipe(reshape)
vals
header A B C D F G
Name Date Added Column 3 Column 4
Bob 10/04/2020 VALUE5 VALUE11 5 0 0 0 0 2
Jack 03/04/2020 VALUE3 VALUE9 0 0 2 0 0 9
John 05/05/2020 VALUE1 VALUE7 1 0 0 5 0 0
Niomi 05/05/2020 VALUE2 VALUE8 0 2 0 7 0 0
Stephanie 10/04/2020 VALUE6 VALUE12 0 1 0 0 1 0
William 01/03/2020 VALUE4 VALUE10 0 0 3 0 5 0
我有一个 table 与下面的简化示例具有相同的结构:
我想将第 1 列和第 2 列转换为 headers 列,并在 C1 值和 C2 值中找到列中的值。 table 的其余部分需要保持不变。我希望结果如下所示:
我找到了一种使用 pd.pivot table 的方法,如下所示,但我有十个 table 列要转换,所以我想一次性完成而不是像下面那样,这意味着我必须 运行 同一行十次,每次都会产生一个新的单独的 table 然后我必须将其合并到之前的输出中。这可能吗,我尝试在 pd.pivot_table 的列和值中使用一个列表,但它不能正常工作,因为它试图组合我给列表的列,而不是仅仅转置它们。有没有一种方法可以按照我在使用 pivot table 时一次性描述的方式转置 table 的一部分,或者是否有其他方法可以让我做到这一点?
TABLE1=pd.DataFrame({'Name':['John','Niomi','Jack','William','Bob','Stephanie'],
'Date Added':['05/05/2020','05/05/2020','03/04/2020','01/03/2020','10/04/2020','10/04/2020'],
'Column 1':['A','B','C','C','A','B'],
'C1 Value':['1','2','2','3','5','1'],
'Column 2':['D','D','G','F','G','F'],
'C2 Value':['5','7','9','5','2','1'],
'Column 3':['VALUE1','VALUE2','VALUE3','VALUE4','VALUE5','VALUE6'],
'Column 4':['VALUE7','VALUE8','VALUE9','VALUE10','VALUE11','VALUE12']})
table2=pd.pivot_table(TABLE1,index=('Name','Date Added'),columns='Column1',values='C1 Value',aggfunc='max',fill_value=0)
table3=pd.pivot_table(TABLE1,index=('Name','Date Added'),columns='Column2',values='C2 Value',aggfunc='max',fill_value=0)
table1.merge(table2,on=['Name','Date Added'])
这里的假设是 table 具有完全相同的列,因此您可以将其变形为一个函数并应用于每个函数:另外,速度大约是您使用枢轴 table.
def reshape(df):
#get various variables that will be reused
other = ['Name','Date Added','Column 3','Column 4']
#contain column 1 and c1 value
var1 = df.columns[df.columns.str.contains('1')].tolist()
#contain column 2 and c2 value
var2 = df.columns[df.columns.str.contains('2')].tolist()
#we'll use this to replace column 1,2 and c1,2
#allows us to merge them
repl = ['header','vals']
#set indices on both var1 and 2, and concat
res = (pd.concat([df.set_index(var1).rename_axis(index=repl).filter(other),
df.set_index(var2).rename_axis(index=repl).filter(other)]
)
#add the remaining indices
.set_index(other,append=True)
#pull out the values
.reset_index(1)
#unstack the header column and fill nulls
.unstack(0,fill_value=0)
)
return res
df.pipe(reshape)
vals
header A B C D F G
Name Date Added Column 3 Column 4
Bob 10/04/2020 VALUE5 VALUE11 5 0 0 0 0 2
Jack 03/04/2020 VALUE3 VALUE9 0 0 2 0 0 9
John 05/05/2020 VALUE1 VALUE7 1 0 0 5 0 0
Niomi 05/05/2020 VALUE2 VALUE8 0 2 0 7 0 0
Stephanie 10/04/2020 VALUE6 VALUE12 0 1 0 0 1 0
William 01/03/2020 VALUE4 VALUE10 0 0 3 0 5 0