Assuming you are starting with a pandas dataframe, we can apply some logical operations before pivoting to your desired output.
from io import StringIO
import pandas as pd
import numpy as np
d = """: What is your full name?
<ANSWER_1>
John Smith
<ANSWER_1>
: What is your Age
<ANSWER_1>
25
<ANSWER_1>
<ANSWER_1>
: Where are you located
<ANSWER_1>
London, fam.
<ANSWER_1>
<ANSWER_2>
Engurrland
<ANSWER_2>
"""
df = pd.read_csv(StringIO(d),sep='\t',header=None)
First, lets build a sequence so we can have a logical order of question + answers and remove any values with <> in the body.
df = df[~df[0].str.contains('<|>')]
df['sequence'] = df.groupby(df[0].str.contains('^:').cumsum()).cumcount()
df['questionSequence'] = np.where(
df[0].str.contains("^:"), df.groupby(df[0].str.contains("^:")).cumcount(), np.nan
)
df['questionSequence'] = df['questionSequence'].ffill()
print(df)
0 sequence questionSequence
0 : What is your full name? 0 0.0
2 John Smith 1 0.0
4 : What is your Age 0 1.0
6 25 1 1.0
9 : Where are you located 0 2.0
11 London, fam. 1 2.0
14 Engurrland 2 2.0
Next, we want to split out the Question column to create a separate question & answer column and remove the pesky colon while we are at it.
df['question'] = np.where(df['sequence'].eq(0),df[0],np.nan)
df['question'] = df['question'].ffill().str.strip(': ')
This is shaping up quite nicely, now lets filter out the questions from column 0 by filtering on the sequence column.
df1 = df1 = df[(df['sequence'].ne(0))].copy()
print(df1)
0 sequence questionSequence question
2 John Smith 1 0.0 What is your full name?
6 25 1 1.0 What is your Age
11 London, fam. 1 2.0 Where are you located
14 Engurrland 2 2.0 Where are you located
finally, we will use a multi index to create your pivot in the same order of the questions.
final = pd.crosstab(
df1["sequence"], [df1["questionSequence"], df1["question"]], df1[0], aggfunc="first"
)
