我的任务是清理慈善机构设计的移动应用程序中的数据
在一个部分中,用户问答应用程序使用会话由一行表示。该部分由重复的问题答案字段对组成,其中一个字段代表所提出的问题,然后它旁边的字段代表相应的答案。每个问题/字段和答案列对一起代表一个独特的问题及其答案。
起始数据
answers.0.answer answers.0.fieldName answers.1.answer answers.1.fieldName
5 0 avoidexercise 0.0 vomitflag
6 156 height 54.0 weight
7 1 affectedkneeside 3.0 painlocationknee
我被要求重新格式化该部分,以便每个问题形成一列,相应的答案成为该列中的一个字段
理想输出
_id avoidexercise enjoyment fatigue2weeks height
5f27f29c362a380d3f9a9e46 1.0 yes 20.0 120.0
5f27f2ac362a380d3f9a9e4b 0.0 no 40.0 180.0
5f27f4d4362a380d3f9a9e52 1.0 yes 50.0 150.0
我的计划是创建许多数据透视表,从彼此的 Q/A 对列中创建,然后连接(外连接)然后内连接以删除重复项
但是,原始数据帧包含数字和对象数据类型的混合
因此,只有一些问题/答案列对似乎正在转换为数据透视表。我尝试过使用各种聚合函数
p1 = ur.pivot_table(index=['_id'],columns= ['answers.0.fieldName'],values=['answers.0.answer'],aggfunc=lambda x: ' '.join(x))
p2 = ur.pivot_table(index=['_id'],columns= ['answers.1.fieldName'],values=['answers.1.answer'],aggfunc=lambda x: ' '.join(x))
p3 = ur.pivot_table(index=['_id'],columns= ['answers.2.fieldName'],values=['answers.2.answer'],aggfunc=lambda x: ' '.join(x))
I have also tried another lambda function
p1 = ur.pivot_table(index=['_id'],columns= ['answers.0.fieldName'],values=['answers.0.answer'],aggfunc=lambda x: ' '.join(str(v) for v in x)
The furthest I have got so far is to run pivots with standard mean aggfunc
p1 = ur.pivot_table(index=['_id'],columns=['answers.0.fieldName'],values=['answers.0.answer'])
ps = [p1,p2,p3]
c = pd.concat(ps)
然后尝试删除合并行和列
df = c.sum(axis=1, level=1, skipna=False)
g = df.groupby('_id').agg(np.sum)
这将返回具有正确形状的数据框
但是,它会丢失对象列中的值,并且我不确定所有数字列的准确度如何
为了解决这个问题,我正在考虑将尽可能多的数据转换为数字
c4 = c.apply(pd.to_numeric, errors='ignore').info()
然后将组合的数据透视表数据框拆分为数字和对象类型
nu = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
cndf = c4.select_dtypes(include=nu)
o = ['object', 'bool', 'datetime64', 'category']
codf = c4.select_dtypes(include=o)
并在数字数据帧上运行与上面相同的 .sum 和 groupby 操作
n1 = cndf.sum(axis=1, level=1, skipna=False)
n2 = n1.groupby('_id').agg(np.sum)
然而,这仍然留下了处理对象列的挑战