2017-08-09 28 views
2

我不知道,怎么我可以做下面的转换:熊猫:包含变量的名称和值的多个列:如何使用Pivot?

我有一个数据帧寻找这样的:

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细节只出现一次。 为了保持复杂:我不确定每个细节是否完全相同(在某些情况下,例如Hometowns而不是家乡)。

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

谢谢!

PS: 可能会有帮助:

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]}) 
+0

我有点被你的数据集不解。举例来说:对于索引2,在我看来,Hometown属于列detail3,另一个属于列detail3_value。 – vestland

+0

你说得对。这是我的问题的原因。你会发现与索引4相同的情况,其中“组”是详细1而不是像其他“组”一样的细节2。否则解决方案将是一个简单的支点。 –

+0

在这种情况下,我认为你应该重新考虑你的初始数据框是如何构建的。将有问题的值移到右边两个步骤并将其替换为None将使得操作更简单。是否有机会从Excel导入? – vestland

回答

1

您可以使用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 
+0

谢谢,这个解决方案对我来说效果很好。 我会很惊讶地了解更多关于lreshape(之前听到的nerver)。有什么区别重塑,为什么我不能找到lreshape的信息? 无论如何,你的解决方案是有用的。 –

+0

很高兴能帮到你,美好的一天! – jezrael

1

可以融化数据帧两次 - 为他们的变量值各一次。然后使用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列的唯一值,并可能与标准化的版本替换其中的一些。

相关问题