2016-08-10 25 views
6

Tôi muốn làm tan một số nhóm cột của một khung dữ liệu thành nhiều cột mục tiêu. Tương tự như câu hỏi Python Pandas Melt Groups of Initial Columns Into Multiple Target Columnspandas dataframe reshaping/stacking of multiple value variables into seperate columns. Tuy nhiên, tôi cần phải làm điều này một cách rõ ràng theo tên cột, chứ không phải theo vị trí chỉ mục.Pandas Làm tan một số nhóm cột thành nhiều cột mục tiêu theo tên

import pandas as pd 
df = pd.DataFrame([('a','b','c',1,2,3,'aa','bb','cc'), ('d', 'e', 'f', 4, 5, 6, 'dd', 'ee', 'ff')], 
        columns=['a_1', 'a_2', 'a_3','b_1', 'b_2', 'b_3','c_1', 'c_2', 'c_3']) 
df 

gốc Dataframe:

id a_1 a_2 a_3 b_1 b_2 b_3 c_1 c_2 c_3 
0 101 a b c 1 2 3 aa bb cc 
1 102 d e f 4 5 6 dd ee ff 

Target Dataframe

 id a b c 
0 101 a 1 aa 
1 101 b 2 bb 
2 101 c 3 cc 
3 102 d 4 dd 
4 102 e 5 ee 
5 102 f 6 ff 

Lời khuyên được nhiều đánh giá về một cách tiếp cận này.

+0

Có một giải pháp trực quan hơn sử dụng chức năng 'pd.wide_to_long' được xây dựng chính xác cho tình huống này. Xem câu trả lời của tôi dưới đây. –

Trả lời

8

Bạn có thể chuyển đổi các tên cột để đa chỉ số dựa trên mô hình cột và sau đó ngăn xếp ở một mức độ cụ thể tùy thuộc vào kết quả mà bạn cần:

import pandas as pd 
df.set_index('id', inplace=True) 
df.columns = pd.MultiIndex.from_tuples(tuple(df.columns.str.split("_"))) 
df.stack(level = 1).reset_index(level = 1, drop = True).reset_index() 

# id a b c  
#101 a 1 aa 
#101 b 2 bb 
#101 c 3 cc 
#102 d 4 dd 
#102 e 5 ee 
#102 f 6 ff 
+1

'df.columns = df.columns.str.split ('_', expand = True)' cũng hoạt động – Happy001

2
cols = df.columns.difference(['id']) 

pd.lreshape(df, cols.groupby(cols.str.split('_').str[0])).sort_values('id') 
Out: 
    id a c b 
0 101 a aa 1 
2 101 b bb 2 
4 101 c cc 3 
1 102 d dd 4 
3 102 e ee 5 
5 102 f ff 6 
+0

Bạn giải thích tại sao "cols.groupby (cols.str.split ('_'). Str [0]) "trả về một dict? – Merlin

+0

[Index.groupby] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Index.groupby.html) trả lại một giá trị. Có lẽ vì làm số học trên chỉ mục không phải là một trường hợp sử dụng phổ biến và nói chung chúng ta cần các nhóm để thay thế. – ayhan

+0

Đó là hành vi bất ngờ, đó là lý do tại sao tôi hỏi. – Merlin

2

Có một cách hiệu quả hơn để làm những loại vấn đề liên quan đến việc làm tan chảy nhiều bộ cột khác nhau. pd.wide_to_long được xây dựng cho những tình huống chính xác này.

pd.wide_to_long(df, stubnames=['a', 'b', 'c'], i='id', j='dropme', sep='_')\ 
    .reset_index()\ 
    .drop('dropme', axis=1)\ 
    .sort_values('id') 

    id a b c 
0 101 a 1 aa 
2 101 b 2 bb 
4 101 c 3 cc 
1 102 d 4 dd 
3 102 e 5 ee 
5 102 f 6 ff 
Các vấn đề liên quan