Skip to content
Advertisement

Transpose 3 column excel with K:V into column Pandas

I have a 3 column excel file I’m reading into pandas with basically k:v pairs in columns

                        stuff     Unnamed: 1            Unnamed: 2
0                    animal:dog            NaN                   NaN
1                   color:brown            NaN                   NaN
2                        age:12            NaN                   NaN
3                  height: 60cm   doctor: mike  visit date: 01/12/21
4   unique animal id:3597230857   doctor id: 2                   NaN
5                           NaN            NaN                   NaN
6                   animal: cat            NaN                   NaN
7                  color: orage            NaN                   NaN
8                        age:21            NaN                   NaN
9                  height: 40cm   doctor: mike                   NaN
10   unique animal id: 95760203   doctor id: 2   visit date:05/21/20
11                          NaN            NaN                   NaN
12                animal: snake            NaN                   NaN
13                 color: orage            NaN                   NaN
14                        age:3  doctor:sally                    NaN
15     unique animal id: 325125    doctor id:1   visit date:05/21/20
16                          NaN            NaN                   NaN
17                          NaN            NaN                   NaN
18                 animal: bird            NaN                   NaN
19                  color: blue            NaN                   NaN
20                 height: 40cm  doctor:sally                    NaN
21  unique animal id: 496701275    doctor id:1   visit date:05/21/20

Process finished with exit code 0

I need to not only tie the information in unnamed:1 & unnamed:2 to the unique animal ID as this is how I will track the animal but also transpose these columns where everything to the left of the “:” is the column header w/ appropriate values.

  animal   color   age  height(cm)  unique animal id doctor  dictir id visit date
0    dog   brown  12.0        60.0        3597230857   mike          2 2021-01-12
1    cat   orage  21.0        40.0          95760203   mike          2 2020-05-21
2  snake  orange   3.0         NaN            325125  sally          1 2020-05-21
3   bird    blue   NaN        40.0         496701275  sally          1 2020-05-21

Currently working off of

    for source in sources:
        df = pd.read_excel(source)
    df['new_heading'] = df['stuff'].str.split(':').str[0]
    df['new_value'] = df['stuff'].str.split(':').str[1]
    df.loc[df['new_heading'] == "animal", 'new_aninmal'] = df['new_value']
    df.loc[df['new_heading'] == "color", 'new_color'] = df['new_value']
    df.loc[df['new_heading'] == "age", 'new_age'] = df['new_value']
    df.loc[df['new_heading'] == "height", 'new_height'] = df['new_value']
    df.loc[df['new_heading'] == "unique animal id", 'new_uid'] = df['new_value']

but it gives this waterfall output (expectedly so)

                          stuff     Unnamed: 1            Unnamed: 2       new_heading   new_value new_aninmal new_color new_age new_height     new_uid
0                    animal:dog            NaN                   NaN            animal         dog         dog       NaN     NaN        NaN         NaN
1                   color:brown            NaN                   NaN             color       brown         NaN     brown     NaN        NaN         NaN
2                        age:12            NaN                   NaN               age          12         NaN       NaN      12        NaN         NaN
3                  height: 60cm   doctor: mike  visit date: 01/12/21            height        60cm         NaN       NaN     NaN       60cm         NaN
4   unique animal id:3597230857   doctor id: 2                   NaN  unique animal id  3597230857         NaN       NaN     NaN        NaN  3597230857
5                           NaN            NaN                   NaN               NaN         NaN         NaN       NaN     NaN        NaN         NaN
6                   animal: cat            NaN                   NaN            animal         cat         cat       NaN     NaN        NaN         NaN
7                  color: orage            NaN                   NaN             color       orage         NaN     orage     NaN        NaN         NaN
8                        age:21            NaN                   NaN               age          21         NaN       NaN      21        NaN         NaN
9                  height: 40cm   doctor: mike                   NaN            height        40cm         NaN       NaN     NaN       40cm         NaN
10   unique animal id: 95760203   doctor id: 2   visit date:05/21/20  unique animal id    95760203         NaN       NaN     NaN        NaN    95760203
11                          NaN            NaN                   NaN               NaN         NaN         NaN       NaN     NaN        NaN         NaN
12                animal: snake            NaN                   NaN            animal       snake       snake       NaN     NaN        NaN         NaN
13                 color: orage            NaN                   NaN             color       orage         NaN     orage     NaN        NaN         NaN
14                        age:3  doctor:sally                    NaN               age           3         NaN       NaN       3        NaN         NaN
15     unique animal id: 325125    doctor id:1   visit date:05/21/20  unique animal id      325125         NaN       NaN     NaN        NaN      325125
16                          NaN            NaN                   NaN               NaN         NaN         NaN       NaN     NaN        NaN         NaN
17                          NaN            NaN                   NaN               NaN         NaN         NaN       NaN     NaN        NaN         NaN
18                 animal: bird            NaN                   NaN            animal        bird        bird       NaN     NaN        NaN         NaN
19                  color: blue            NaN                   NaN             color        blue         NaN      blue     NaN        NaN         NaN
20                 height: 40cm  doctor:sally                    NaN            height        40cm         NaN       NaN     NaN       40cm         NaN
21  unique animal id: 496701275    doctor id:1   visit date:05/21/20  unique animal id   496701275         NaN       NaN     NaN        NaN   496701275

Advertisement

Answer

Each section starts with animal, so create a counter that acknowledges that. the counter will be used in pivoting the data:

reshape = (
    df.assign(counter=np.where(df.stuff.str.startswith("animal:"), 1, 0).cumsum())
    .melt("counter")
    .dropna()
    .drop(columns="variable")
)

Here we split the column with : and pivot the data; the counter ensures a unique index, which is required for a successful pivot:

    (
    reshape.value.str.split(":", expand=True)
    .assign(counter=reshape.counter)
    .pivot("counter", 0, 1)
)
    

        age     animal  color   doctor  doctor id   height  unique animal id    visit date
counter                                 
1       12      dog     brown   mike      2        60cm     3597230857  01/12/21
3       21      cat     orage   mike      2        40cm     95760203    05/21/20
5       3       snake   orage   sally     1         NaN     325125  05/21/20
8      NaN      bird    blue    sally     1        40cm     496701275   05/21/20
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement