I have a 3 column excel file I’m reading into pandas with basically k:v pairs in columns
JavaScript
26
1
stuff Unnamed: 1 Unnamed: 2
2
0 animal:dog NaN NaN
3
1 color:brown NaN NaN
4
2 age:12 NaN NaN
5
3 height: 60cm doctor: mike visit date: 01/12/21
6
4 unique animal id:3597230857 doctor id: 2 NaN
7
5 NaN NaN NaN
8
6 animal: cat NaN NaN
9
7 color: orage NaN NaN
10
8 age:21 NaN NaN
11
9 height: 40cm doctor: mike NaN
12
10 unique animal id: 95760203 doctor id: 2 visit date:05/21/20
13
11 NaN NaN NaN
14
12 animal: snake NaN NaN
15
13 color: orage NaN NaN
16
14 age:3 doctor:sally NaN
17
15 unique animal id: 325125 doctor id:1 visit date:05/21/20
18
16 NaN NaN NaN
19
17 NaN NaN NaN
20
18 animal: bird NaN NaN
21
19 color: blue NaN NaN
22
20 height: 40cm doctor:sally NaN
23
21 unique animal id: 496701275 doctor id:1 visit date:05/21/20
24
25
Process finished with exit code 0
26
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.
JavaScript
6
1
animal color age height(cm) unique animal id doctor dictir id visit date
2
0 dog brown 12.0 60.0 3597230857 mike 2 2021-01-12
3
1 cat orage 21.0 40.0 95760203 mike 2 2020-05-21
4
2 snake orange 3.0 NaN 325125 sally 1 2020-05-21
5
3 bird blue NaN 40.0 496701275 sally 1 2020-05-21
6
Currently working off of
JavaScript
10
1
for source in sources:
2
df = pd.read_excel(source)
3
df['new_heading'] = df['stuff'].str.split(':').str[0]
4
df['new_value'] = df['stuff'].str.split(':').str[1]
5
df.loc[df['new_heading'] == "animal", 'new_aninmal'] = df['new_value']
6
df.loc[df['new_heading'] == "color", 'new_color'] = df['new_value']
7
df.loc[df['new_heading'] == "age", 'new_age'] = df['new_value']
8
df.loc[df['new_heading'] == "height", 'new_height'] = df['new_value']
9
df.loc[df['new_heading'] == "unique animal id", 'new_uid'] = df['new_value']
10
but it gives this waterfall output (expectedly so)
JavaScript
25
1
stuff Unnamed: 1 Unnamed: 2 new_heading new_value new_aninmal new_color new_age new_height new_uid
2
0 animal:dog NaN NaN animal dog dog NaN NaN NaN NaN
3
1 color:brown NaN NaN color brown NaN brown NaN NaN NaN
4
2 age:12 NaN NaN age 12 NaN NaN 12 NaN NaN
5
3 height: 60cm doctor: mike visit date: 01/12/21 height 60cm NaN NaN NaN 60cm NaN
6
4 unique animal id:3597230857 doctor id: 2 NaN unique animal id 3597230857 NaN NaN NaN NaN 3597230857
7
5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
8
6 animal: cat NaN NaN animal cat cat NaN NaN NaN NaN
9
7 color: orage NaN NaN color orage NaN orage NaN NaN NaN
10
8 age:21 NaN NaN age 21 NaN NaN 21 NaN NaN
11
9 height: 40cm doctor: mike NaN height 40cm NaN NaN NaN 40cm NaN
12
10 unique animal id: 95760203 doctor id: 2 visit date:05/21/20 unique animal id 95760203 NaN NaN NaN NaN 95760203
13
11 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
14
12 animal: snake NaN NaN animal snake snake NaN NaN NaN NaN
15
13 color: orage NaN NaN color orage NaN orage NaN NaN NaN
16
14 age:3 doctor:sally NaN age 3 NaN NaN 3 NaN NaN
17
15 unique animal id: 325125 doctor id:1 visit date:05/21/20 unique animal id 325125 NaN NaN NaN NaN 325125
18
16 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
19
17 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
20
18 animal: bird NaN NaN animal bird bird NaN NaN NaN NaN
21
19 color: blue NaN NaN color blue NaN blue NaN NaN NaN
22
20 height: 40cm doctor:sally NaN height 40cm NaN NaN NaN 40cm NaN
23
21 unique animal id: 496701275 doctor id:1 visit date:05/21/20 unique animal id 496701275 NaN NaN NaN NaN 496701275
24
25
Advertisement
Answer
Each section starts with animal
, so create a counter that acknowledges that. the counter will be used in pivoting the data:
JavaScript
7
1
reshape = (
2
df.assign(counter=np.where(df.stuff.str.startswith("animal:"), 1, 0).cumsum())
3
.melt("counter")
4
.dropna()
5
.drop(columns="variable")
6
)
7
Here we split the column with :
and pivot the data; the counter ensures a unique index, which is required for a successful pivot:
JavaScript
14
1
(
2
reshape.value.str.split(":", expand=True)
3
.assign(counter=reshape.counter)
4
.pivot("counter", 0, 1)
5
)
6
7
8
age animal color doctor doctor id height unique animal id visit date
9
counter
10
1 12 dog brown mike 2 60cm 3597230857 01/12/21
11
3 21 cat orage mike 2 40cm 95760203 05/21/20
12
5 3 snake orage sally 1 NaN 325125 05/21/20
13
8 NaN bird blue sally 1 40cm 496701275 05/21/20
14