像在 Qlik 中一样在 Pandas 中执行 Crosstable?
Doing Crosstable in Pandas like in Qlik?
我有一个数据框:
df1=pd.DataFrame({
'ID':[101,102],
'Name':['Axel','Bob'],
'US':['GrA','GrC'],
'Europe':['GrB','GrD'],
'AsiaPac':['GrZ','GrF']
})
我想改成这个:
df2=pd.DataFrame({
'ID':[101,101,101,102,102,102],
'Name':['Axel','Axel','Axel','Bob','Bob','Bob'],
'Region':['US','Europe','AsiaPac','US','Europe','AsiaPac'],
'Group':['GrA','GrB','GrZ','GrC','GrD','GrF']
})
我该怎么做? pandas 中有一个交叉表函数,但它不执行此操作。在 Qlik 中我会简单地做
Crosstable(Region,Group,2)
LOAD
ID,
Name,
US,
Europe,
AsiaPac
我会从 df1 转到 df2。如何在 python(pandas 或其他方式)中执行此操作?
这实质上是将您的数据从宽格式重塑为长格式,正如 R 语言中所说的那样。在 pandas 中,您可以使用 pd.melt
:
pd.melt(df1, id_vars=['ID', 'Name'], var_name='Region', value_name='Group')
# ID Name Region Group
# 0 101 Axel AsiaPac GrZ
# 1 102 Bob AsiaPac GrF
# 2 101 Axel Europe GrB
# 3 102 Bob Europe GrD
# 4 101 Axel US GrA
# 5 102 Bob US GrC
如果您需要按 ID
或 Name
和 Group
对列进行排序,如示例输出中所示,您可以将 .sort_values()
添加到表达式中:
pd.melt(df1, id_vars=['ID', 'Name'], var_name='Region', value_name='Group').sort_values(['ID', 'Group'])
# ID Name Region Group
# 4 101 Axel US GrA
# 2 101 Axel Europe GrB
# 0 101 Axel AsiaPac GrZ
# 5 102 Bob US GrC
# 3 102 Bob Europe GrD
# 1 102 Bob AsiaPac GrF
你可以试试
第 1
stack()
df1.set_index(['ID','Name']).stack().reset_index().rename(columns={'level_2':'Region',0:'Group'})
Out[890]:
ID Name Region Group
0 101 Axel AsiaPac GrZ
1 101 Axel Europe GrB
2 101 Axel US GrA
3 102 Bob AsiaPac GrF
4 102 Bob Europe GrD
5 102 Bob US GrC
第二
pd.wide_to_long
,即使是矫枉过正。 :)
df1=df1.rename(columns={'AsiaPac':'Group_AsiaPac','Europe':'Group_Europe','US':'Group_US'})
pd.wide_to_long(df1,['Group'], i=['ID','Name'], j='Region',sep='_',suffix='.').reset_index()
Out[918]:
ID Name Region Group
0 101 Axel AsiaPac GrZ
1 101 Axel Europe GrB
2 101 Axel US GrA
3 102 Bob AsiaPac GrF
4 102 Bob Europe GrD
5 102 Bob US GrC
我有一个数据框:
df1=pd.DataFrame({
'ID':[101,102],
'Name':['Axel','Bob'],
'US':['GrA','GrC'],
'Europe':['GrB','GrD'],
'AsiaPac':['GrZ','GrF']
})
我想改成这个:
df2=pd.DataFrame({
'ID':[101,101,101,102,102,102],
'Name':['Axel','Axel','Axel','Bob','Bob','Bob'],
'Region':['US','Europe','AsiaPac','US','Europe','AsiaPac'],
'Group':['GrA','GrB','GrZ','GrC','GrD','GrF']
})
我该怎么做? pandas 中有一个交叉表函数,但它不执行此操作。在 Qlik 中我会简单地做
Crosstable(Region,Group,2)
LOAD
ID,
Name,
US,
Europe,
AsiaPac
我会从 df1 转到 df2。如何在 python(pandas 或其他方式)中执行此操作?
这实质上是将您的数据从宽格式重塑为长格式,正如 R 语言中所说的那样。在 pandas 中,您可以使用 pd.melt
:
pd.melt(df1, id_vars=['ID', 'Name'], var_name='Region', value_name='Group')
# ID Name Region Group
# 0 101 Axel AsiaPac GrZ
# 1 102 Bob AsiaPac GrF
# 2 101 Axel Europe GrB
# 3 102 Bob Europe GrD
# 4 101 Axel US GrA
# 5 102 Bob US GrC
如果您需要按 ID
或 Name
和 Group
对列进行排序,如示例输出中所示,您可以将 .sort_values()
添加到表达式中:
pd.melt(df1, id_vars=['ID', 'Name'], var_name='Region', value_name='Group').sort_values(['ID', 'Group'])
# ID Name Region Group
# 4 101 Axel US GrA
# 2 101 Axel Europe GrB
# 0 101 Axel AsiaPac GrZ
# 5 102 Bob US GrC
# 3 102 Bob Europe GrD
# 1 102 Bob AsiaPac GrF
你可以试试
第 1
stack()
df1.set_index(['ID','Name']).stack().reset_index().rename(columns={'level_2':'Region',0:'Group'})
Out[890]:
ID Name Region Group
0 101 Axel AsiaPac GrZ
1 101 Axel Europe GrB
2 101 Axel US GrA
3 102 Bob AsiaPac GrF
4 102 Bob Europe GrD
5 102 Bob US GrC
第二
pd.wide_to_long
,即使是矫枉过正。 :)
df1=df1.rename(columns={'AsiaPac':'Group_AsiaPac','Europe':'Group_Europe','US':'Group_US'})
pd.wide_to_long(df1,['Group'], i=['ID','Name'], j='Region',sep='_',suffix='.').reset_index()
Out[918]:
ID Name Region Group
0 101 Axel AsiaPac GrZ
1 101 Axel Europe GrB
2 101 Axel US GrA
3 102 Bob AsiaPac GrF
4 102 Bob Europe GrD
5 102 Bob US GrC