使用 Pandas 的 SurveyMonkey 数据格式化

Posted

技术标签:

【中文标题】使用 Pandas 的 SurveyMonkey 数据格式化【英文标题】:SurveyMonkey data formatting using Pandas 【发布时间】:2018-09-09 21:01:51 【问题描述】:

我有一个调查要分析,该调查由 SurveyMonkey 的参与者完成。不幸的是,数据的组织方式并不理想,因为每个问题的每个分类响应都有自己的列。

例如,这里是数据框中的一个响应的前几行:

     How long have you been participating in the Garden Awards Program?  \
0                                           One year                   
1                                                NaN                   
2                                                NaN                   
3                                                NaN                   
4                                                NaN                   

  Unnamed: 10 Unnamed: 11      Unnamed: 12  \
0   2-3 years   4-5 years  5 or more years   
1         NaN         NaN              NaN   
2         NaN   4-5 years              NaN   
3   2-3 years         NaN              NaN   
4         NaN         NaN  5 or more years   

  How did you initially learn of the Garden Awards Program?  \
0              I nominated my garden to be evaluated          
1                                                NaN          
2              I nominated my garden to be evaluated          
3                                                NaN          
4                                                NaN          

                                         Unnamed: 14  etc...
0  A friend or family member nominated my garden ...  
1  A friend or family member nominated my garden ...  
2                                                NaN  
3                                                NaN  
4                                                NaN  

这个问题,How long have you been participating in the Garden Awards Program?,有有效的回答:one year2-3 years 等,并且都在第一行作为哪个列保存哪个值的键。这是第一个问题。 (How did you initially learn of the Garden Awards Program? 也是如此,其中有效的响应是:I nominated my garden to be evaluatedA friend or family member nominated my garden 等)。

第二个问题是每个分类响应的附加列都是Unnamed: N,其中 N 是与所有问题相关联的类别一样多的列。

在我开始将每个问题的列重新映射和展平/折叠成一个列之前,我想知道是否有任何其他方法可以使用 Pandas 处理像这样呈现的调查数据。我的所有搜索都指向了 SurveyMonkey API,但我看不出它有什么用处。

我猜我需要展平列,因此,如果有人能提出一种方法,那就太好了。我在想有一种方法可以通过抓取相邻的列来继续抓取属于分类响应的所有列,直到 Unnamed 不再在列名中,但我不知道如何做到这一点。

【问题讨论】:

您能否将 DataFrame 的前几行作为文本而不是图像发布? 按要求完成。一个主要问题是,有很多这些分组的分类响应列,每个列跨越每个问题的几个列,因此重新映射这些将是一个皇家 PITA。 【参考方案1】:

我将使用以下DataFrame(可以从here下载为CSV):

     Q1 Unnamed: 2 Unnamed: 3    Q2 Unnamed: 5 Unnamed: 6    Q3 Unnamed: 7 Unnamed: 8
0  A1-A       A1-B       A1-C  A2-A       A2-B       A2-C  A3-A       A4-B       A3-C
1  A1-A        NaN        NaN   NaN       A2-B        NaN   NaN        NaN       A3-C
2   NaN       A1-B        NaN  A2-A        NaN        NaN   NaN       A4-B        NaN
3   NaN        NaN       A1-C   NaN       A2-B        NaN  A3-A        NaN        NaN
4   NaN       A1-B        NaN   NaN        NaN       A2-C   NaN        NaN       A3-C
5  A1-A        NaN        NaN   NaN       A2-B        NaN  A3-A        NaN        NaN

关键假设:

    名称不以Unnamed 开头的每一列实际上都是问题的标题 问题标题之间的列代表列间隔左端问题的选项

解决方案概述:

    查找每个问题开始和结束位置的索引 将每个问题扁平化为一列 (pd.Series) 将问题列重新合并在一起

实施(第 1 部分):

indices = [i for i, c in enumerate(df.columns) if not c.startswith('Unnamed')]
questions = [c for c in df.columns if not c.startswith('Unnamed')]
slices = [slice(i, j) for i, j in zip(indices, indices[1:] + [None])]

您可以看到,像下面这样对切片进行迭代,您会得到一个与每个问题相对应的 DataFrame

for q in slices:
    print(df.iloc[:, q])  # Use `display` if using Jupyter

实施(第 2-3 部分):

def parse_response(s):
    try:
        return s[~s.isnull()][0]
    except IndexError:
        return np.nan

data = [df.iloc[:, q].apply(parse_response, axis=1)[1:] for q in slices]
df = pd.concat(data, axis=1)
df.columns = questions

输出:

     Q1    Q2    Q3
1  A1-A  A2-B  A3-C
2  A1-B  A2-A  A4-B
3  A1-C  A2-B  A3-A
4  A1-B  A2-C  A3-C
5  A1-A  A2-B  A3-A

【讨论】:

不错!我是按照这些思路思考的,但这是完美的! 唯一的问题是假设 3 不一定成立。我在我的数据集上的implementation (part 2-3) 的第一步中收到('index out of bounds', 'occurred at index 1') 的错误,并且可以在您的数据集上重现,当连续响应的所有值都是 NaN、IOW 时,没有非空响应针对特定调查中的特定调查项目。 我将尝试在执行列表理解的步骤中使用np.where 子句,这样如果所有项目都是null,那么我会将值设置为no response否则它将是~s.isnull()][0] 或类似的东西...... @horcle_buzz:你可以创建一个更通用的函数,而不是使用np.where。我编辑了帖子,用常规命名函数 parse_response 替换了 lambda 函数,该函数涵盖了没有有效响应可用的情况。 Gustavo Bezzerra,谢谢。我确实提出了一个完全不同的解决方案,稍后我将发布(不使用np.where)。

以上是关于使用 Pandas 的 SurveyMonkey 数据格式化的主要内容,如果未能解决你的问题,请参考以下文章

使用 R 解析出 Surveymonkey csv 文件

使用surveymonkey api向调查发布电子邮件

SurveyMonkey API v3 创建消息,返回错误:“用户没有发出此请求所需的计划”

text 来自surveymonkey的回调

如何在 SurveyMonkey v3 响应/批量中按 date_modified 以外的字段排序

XSLT以递归方式重组XML Children