Python3,Pandas - 基于列到左侧数据的新列值(动态)

问题描述:

我有一个包含调查响应的几列的电子表格。这个电子表格将被合并到其他电子表格中,然后我将有与下面类似的重复行。然后,我将需要采用相同文本的所有问题,并根据整个合并文档计算答案的百分比。Python3,Pandas - 基于列到左侧数据的新列值(动态)

例Excel数据

**Poll Question**              **Poll Responses** 
The content was clear and effectively delivered       37 Total Votes 
Strongly Agree               24.30% 
Agree                 70.30% 
Neutral                 2.70% 
Disagree                2.70% 
Strongly Disagree              0.00% 
The Instructor(s) were engaging and motivating        37 Total Votes 
Strongly Agree               21.60% 
Agree                 73.00% 
Neutral                 2.70% 
Disagree                2.70% 
Strongly Disagree              0.00% 
I would attend another training session delivered by this Instructor(s) 37 Total Votes 
Strongly Agree               21.60% 
Agree                 73.00% 
Neutral                 5.40% 
Disagree                0.00% 
Strongly Disagree              0.00% 
This was a good format for my training          37 Total Votes 
Strongly Agree               24.30% 
Agree                 62.20% 
Neutral                 8.10% 
Disagree                2.70% 
Strongly Disagree              2.70% 
Any comments/suggestions about this training course?      5 Total Votes 

我的用于计算票的非%的数目的方法将是百分比转换为数字。例如。从37 Total Votes中查找并提取37,然后使用以下公式获取在该特定答案上投票的用户数:percent * total/100

所以24.30 * 37/100 = 8.99舍入意味着37人中有9人投票赞成“非常同意”。

这里是希望我能够做一个例子电子表格

**Poll Question** **Poll Responses** **non-percent** **subtotal** 
    ...     37 Total Votes  0    37 
    ...     24.30%    9    37 
    ...     70.30%    26    37 
    ...     2.70%    1    37 
    ...     2.70%    1    37 
    ...     0.00%    0    37 

(注:非百分之大部将新创建的列)

目前我拿着一个文件夹完整的.xls文件,我循环通过该文件夹,以.xlsx格式保存到另一个文件夹。在该循环内,我添加了一个注释块,其中包含我的# NEW test CODE,我试图将逻辑放在此处。你可以看到,我试图定位单元格并获取值,然后得到一些正则表达式并从中提取数字(然后将它添加到该行中的subtotal列。然后我想添加。它,直到我看到

x Total Votes行的新实例这里是我当前的代码

import numpy as np 
import pandas as pd 

files = get_files('/excels/', '.xls') 
df_array = [] 

for i, f in enumerate(files, start=1): 
    sheet = pd.read_html(f, attrs={'class' : 'reportData'}, flavor='bs4') 
    event_id = get_event_id(pd.read_html(f, attrs={'id' : 'eventSummary'})) 
    event_title= get_event_title(pd.read_html(f, attrs={'id' : 'eventSummary'})) 
    filename = event_id + '.xlsx' 
    rel_path = 'xlsx/' + filename 
    writer = pd.ExcelWriter(rel_path) 

    for df in sheet: 
     # NEW test CODE 
     q_total = 0 
     df.columns = df.columns.str.strip() 
     if df[df['Poll Responses'].str.contains("Total Votes")]: 
     # if df['Poll Responses'].str.contains("Total Votes"): 
      q_total = re.findall(r'.+?(?=\sTotal\sVotes)', df['Poll Responses'].str.contains("Total Votes"))[0] 
      print(q_total) 
     # df['Question Total'] = np.where(df['Poll Responses'].str.contains("Total Votes"), 'yes', 'no') 
     # END NEW test Code 
     df.insert(0, 'Event ID', event_id) 
     df.insert(1, 'Event Title', event_title) 
     df.to_excel(writer,'sheet') 
     writer.save() 

    # progress of entire list 
    if i <= len(files): 
     print('\r{:*^10}{:.0f}%'.format('Converting: ', i/len(files)*100), end='') 

print('\n') 

TL; DR 这似乎很令人费解,但如果我能得到两个新的列包含一个问题的总票数和一个答案的票数(不是百分比),那么我可以在合并的文档上做一些VLOOKUP魔术。任何帮助或方法的建议将不胜感激。谢谢!

+0

对于每个问题,你总会有相同数量的答案吗?您可以在每张表格中读入数据框,然后将它们添加到一起。其余的是熊猫。 – Kyle

+0

可悲的是,没有。因为可能存在“评论框”类问题,并且它不会与其他人分开5行。或者用户可能会选择不做类似于样式的测试。 – Kenny

我解决了这个,我会后下面的伪代码:通过每片

  1. 我循环。在该循环中,我使用for n, row in enumerate(df.itertuples(), 1):循环遍历每一行。
  2. 我得到的可能含有“人头响应” poll_response = str(row[3])
  3. 使用的if/else我检查poll_response包含文本“总投票”的字段的值。如果确实如此,那一定是一个问题,否则它必须是一排答案。
  4. 在这个问题的if我得到包含我需要的数据的单元格。然后我有一个函数将问题文本与数组中的所有对象问题文本进行比较。如果它是匹配的,那么我只需更新对象的字段,否则我会创建一个新的问题对象。
  5. else行是答案行,我使用问题文本来查找数组中的对象并更新/添加答案或数据。
  6. 此过程循环遍历每个电子表格中的所有行,现在我的数组充满了唯一的问题对象。