2017-08-09 75 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列的唯一值,並可能與標準化的版本替換其中的一些。

相關問題