熊猫:包含变量名称和值的多个列:如何使用透视?



我不确定是否以及如何进行以下转换:

我有一个看起来像这样的数据帧:

Index   Name    detail1 detail1_value   detail2  detail2_value   detail3    detail3_value
1     Albert    Age      30             Group       A            Hometown   beautifulplace
2     Bea       Age      28             Hometown    anotherplace None       None
3     Celin     Age      45             Group       B            None       None
4     Dave      Group    A              None        None         None       None

但正如你可以想象的那样,我的目标是:

Index   Name    Age Group   Hometown
1     Albert    30  A   beautifulplace
2     Bea       28      anotherplace
3     Celin     45  B   
4     Dave          A   

我很确定ech细节只出现一次。 为了使事情变得复杂:我不确定每个细节是否完全相同(在某些情况下,例如家乡而不是家乡(。

到目前为止,我能看到的唯一解决方案是从每对列(如 detail1 和 detail1_value(中生成单个数据透视表。在第二步中,创建一个新数据集,例如在年龄信息上搜索每个数据透视表。 但我对python的信任告诉我,一定有更好的方法......

谢谢!

附注: 可能有助于:

dataset = pd.DataFrame({'Name': ['Albert', 'Bea', 'Celine', 'Dave'],
'detail1': ['Age', 'Age', 'Age', 'Group'],
'detail1_value': ['30', '28', '45', 'A'],
'detail2': ['Group', 'Hometown', 'Group', None],
'detail2_value': ['A', 'anotherplace', 'B', None],
'detail3': ['Hometown', None, None, None],
'detail3_value': ['beautifulplace', None, None, None]})

您可以将lreshapepivot一起使用:

#get columns names dynamically 
a = dataset.columns[dataset.columns.str.endswith('_value')]
b = dataset.columns[dataset.columns.str.startswith('detail')].difference(a)
df = pd.lreshape(dataset, {'detail':b, 'value':a})
print (df)
Name           value    detail
0  Albert              30       Age
1     Bea              28       Age
2  Celine              45       Age
3    Dave               A     Group
4  Albert               A     Group
5     Bea    anotherplace  Hometown
6  Celine               B     Group
7  Albert  beautifulplace  Hometown

df = df.pivot(index='Name', columns='detail', values='value')
print (df)
detail   Age Group        Hometown
Name                              
Albert    30     A  beautifulplace
Bea       28  None    anotherplace
Celine    45     B            None
Dave    None     A            None

一些数据清理最后:

df = df.reset_index().rename_axis(None, axis=1)
print (df)
Name   Age Group        Hometown
0  Albert    30     A  beautifulplace
1     Bea    28  None    anotherplace
2  Celine    45     B            None
3    Dave  None     A            None

可以融合数据帧两次 - 一次用于变量,一次用于其值。然后使用 Name 以及此变量来自哪个详细信息将它们合并回来。合并的数据帧应已准备好进行透视,请参阅以下示例:

id_cols  = ['Name']
var_cols = ['detail1','detail2','detail3']
val_cols = ['detail1_value','detail2_value','detail3_value']
val_var_mapping = {k:v for k,v in zip(val_cols, var_cols)}
# extract variables
variables = dataset[id_cols+var_cols].melt(id_vars=['Name'],
value_name='variable',var_name='detail')
# print(variables.head())
#      Name   detail variable
# 0  Albert  detail1      Age
# 1     Bea  detail1      Age
# 2  Celine  detail1      Age
# 3    Dave  detail1    Group
# 4  Albert  detail2    Group
# extract values
values = dataset[id_cols+val_cols].melt(id_vars=['Name'], var_name='detail')
values['detail'] = values['detail'].replace(val_var_mapping)
# print(values.head())
#      Name   detail value
# 0  Albert  detail1    30
# 1     Bea  detail1    28
# 2  Celine  detail1    45
# 3    Dave  detail1     A
# 4  Albert  detail2     A
# merge and pivot
res = (variables.dropna()
.merge(values, on=id_cols+['detail'])
.pivot(index='Name',columns='variable',values='value')
)
# print(res)
# variable   Age Group        Hometown
# Name                                
# Albert      30     A  beautifulplace
# Bea         28  None    anotherplace
# Celine      45     B            None
# Dave      None     A            None

至于家乡与家乡,您可以检查variable列的唯一值,并可能用标准化版本替换其中一些。

最新更新