简体   繁体   中英

How to change data structure with pandas (unpivot)

Following CSV with sampledata is given:

Projectname;Step 1 Start;Step 1 End;Step 2 Start;Step 2 End;Step 3 Start;Step 3 End;…;…;Step 21 Start;Step 21 End
Project A;01.01.2020;02.01.2020;02.01.2020;03.01.2020;03.01.2020;04.01.2020;…;…;21.01.2020;22.01.2020
Project B;01.02.2020;02.02.2020;02.02.2020;03.02.2020;03.02.2020;04.02.2020;…;…;21.02.2020;22.02.2020
Project C;01.03.2020;02.03.2020;02.03.2020;03.03.2020;03.03.2020;04.03.2020;…;…;21.03.2020;22.03.2020

Each row represents one project. Each project has 21 steps. For each step is a column with a start timestamp and a column with a end timestamp. In total 42 columns with timestamps.

What I need is a CSV with following structure:

Projectname;Stepname;Start;End
Project A;Step 1;01.01.2020;02.01.2020
Project A;Step 2;02.01.2020;03.01.2020
Project A;Step 3;03.01.2020;04.01.2020
Project A;Step 21;21.01.2020;22.01.2020
Project B;Step 1;01.02.2020;02.02.2020
Project B;Step 2;02.02.2020;03.02.2020
Project B;Step 3;03.02.2020;04.02.2020
Project B;Step 21;21.02.2020;22.02.2020
Project C;Step 1;01.03.2020;02.03.2020
Project C;Step 2;02.03.2020;03.03.2020
Project C;Step 3;03.03.2020;04.03.2020
Project C;Step 21;21.03.2020;22.03.2020

Each row represents one step with start and end timestamp. Can I do this data structure transformation with pandas (also other modules are welcome), and how?

First was replaced order of values in columns names with Series.str.replace :

df.columns = df.columns.str.replace(r'(Step \d+)\s+(Start|End)', r'\2_\1')
print (df)
  Projectname Start_Step 1  End_Step 1 Start_Step 2  End_Step 2 Start_Step 3  \
0   Project A   01.01.2020  02.01.2020   02.01.2020  03.01.2020   03.01.2020   
1   Project B   01.02.2020  02.02.2020   02.02.2020  03.02.2020   03.02.2020   
2   Project C   01.03.2020  02.03.2020   02.03.2020  03.03.2020   03.03.2020   

   End_Step 3 Start_Step 21 End_Step 21  
0  04.01.2020    21.01.2020  22.01.2020  
1  04.02.2020    21.02.2020  22.02.2020  
2  04.03.2020    21.03.2020  22.03.2020 

So is possible use wide_to_long :

df = pd.wide_to_long(df, 
                     stubnames=['Start','End'], 
                     i='Projectname', 
                     j='Stepname', 
                     sep='_', 
                     suffix='Step \d+').reset_index()
print (df)
   Projectname Stepname       Start         End
0    Project A   Step 1  01.01.2020  02.01.2020
1    Project B   Step 1  01.02.2020  02.02.2020
2    Project C   Step 1  01.03.2020  02.03.2020
3    Project A   Step 2  02.01.2020  03.01.2020
4    Project B   Step 2  02.02.2020  03.02.2020
5    Project C   Step 2  02.03.2020  03.03.2020
6    Project A   Step 3  03.01.2020  04.01.2020
7    Project B   Step 3  03.02.2020  04.02.2020
8    Project C   Step 3  03.03.2020  04.03.2020
9    Project A  Step 21  21.01.2020  22.01.2020
10   Project B  Step 21  21.02.2020  22.02.2020
11   Project C  Step 21  21.03.2020  22.03.2020

You Can use pandas wide to long

Example from documentation:

df = pd.DataFrame({
    'famid': [1, 1, 1, 2, 2, 2, 3, 3, 3],
    'birth': [1, 2, 3, 1, 2, 3, 1, 2, 3],
    'ht1': [2.8, 2.9, 2.2, 2, 1.8, 1.9, 2.2, 2.3, 2.1],
    'ht2': [3.4, 3.8, 2.9, 3.2, 2.8, 2.4, 3.3, 3.4, 2.9]
})
df


 famid  birth  ht1  ht2
0      1      1  2.8  3.4
1      1      2  2.9  3.8
2      1      3  2.2  2.9
3      2      1  2.0  3.2
4      2      2  1.8  2.8
5      2      3  1.9  2.4
6      3      1  2.2  3.3
7      3      2  2.3  3.4
8      3      3  2.1  2.9


l = pd.wide_to_long(df, stubnames='ht', i=['famid', 'birth'], j='age')
l

                  ht
famid birth age
1     1     1    2.8
            2    3.4
      2     1    2.9
            2    3.8
      3     1    2.2
            2    2.9
2     1     1    2.0
            2    3.2
      2     1    1.8
            2    2.8
      3     1    1.9
            2    2.4
3     1     1    2.2
            2    3.3
      2     1    2.3
            2    3.4
      3     1    2.1
            2    2.9

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM