代码之家  ›  专栏  ›  技术社区  ›  tavalendo

从excel多表文件解析:列之间的列表理解

  •  1
  • tavalendo  · 技术社区  · 7 年前

    我正试图分析一个有许多工作表的excel文件。每一页都有一列,其中包含以下信息(3页=3列):

    ReceivedEmail    OpenedEmail    ClickedURL
    aaaa@aaa.com     gggg@aaa.com   aaaa@aaa.com
    bbbb@aaa.com     dddd@aaa.com   rrrr@aaa.com
    cccc@aaa.com     rrrr@aaa.com
    dddd@aaa.com     aaaa@aaa.com
    eeee@aaa.com     oooo@aaa.com
    ffff@aaa.com
    gggg@aaa.com
    rrrr@aaa.com
    qqqq@aaa.com
    oooo@aaa.com
    

    我想要的是一个单独的表格,它保留了第一张表格的第一列,也就是说,它包含了所有关于receivedemail(我们群发电子邮件的人)的数据。下一列应该是后续工作表的第一列,但我不想重复电子邮件,而是想使用列表理解来检查receivedemail中是否存在openedemail,并给出 否则给 .

    我到目前为止所做的是:

    import pandas as pd
    xl = pd.ExcelFile(path_to_file)
    xl.sheet_names
    ['ReceivedEmail', 'OpenedEmail', 'ClickedURL']
    df = xl.parse(sheet_name=xl.sheet_names[0], header=None)
    df.rename(columns={df.columns[0]:xl.sheet_names[0]}, inplace=True);
    df.columns[0]
    ['ReceivedEmail']
    # then I created a buffer dataframe to check next columns
    df_buffer = xl.parse(sheet_name=xl.sheet_names[1], header=None)
    df_buffer.rename(columns={df_buffer.columns[0]:xl.sheet_names[1]}, inplace=True);
    

    但是当我像这样运行列表理解时:

    df[df_buffer.columns[0]] = [1 if x in df[df.columns[0]] else 0 for x in df_buffer[df_buffer.columns[0]]]
    

    我得到一个错误:

    值错误:值的长度与索引的长度不匹配

    有什么线索可以解决这个错误或者用一种聪明的方式处理这个问题吗?我正在手动操作以查看它是否有效,然后我可以稍后执行循环操作,但我被错误卡住了。

    最终结果应该是:

    ReceivedEmail    OpenedEmail    ClickedURL
    aaaa@aaa.com         1              1
    bbbb@aaa.com         0              0      
    cccc@aaa.com         0              0     
    dddd@aaa.com         1              0
    eeee@aaa.com         0              0    
    ffff@aaa.com         0              0  
    gggg@aaa.com         1              0
    rrrr@aaa.com         1              1
    qqqq@aaa.com         0              0
    oooo@aaa.com         1              0
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   jezrael    7 年前

    你可以使用 read_excel 带参数 sheetname=None 要将所有工作表返回到数据帧的有序字典,请执行以下操作:

    注意事项:

    每张纸有一列。

    dfs = pd.read_excel('file.xlsx', sheetname=None)
    print (dfs)
    OrderedDict([('ReceivedEmail',               a
    0  aaaa@aaa.com
    1  bbbb@aaa.com
    2  cccc@aaa.com
    3  dddd@aaa.com
    4  eeee@aaa.com
    5  ffff@aaa.com
    6  gggg@aaa.com
    7  rrrr@aaa.com
    8  qqqq@aaa.com
    9  oooo@aaa.com), ('OpenedEmail',               a
    0  gggg@aaa.com
    1  dddd@aaa.com
    2  rrrr@aaa.com
    3  aaaa@aaa.com
    4  oooo@aaa.com), ('ClickedURL',               a
    0  aaaa@aaa.com
    1  rrrr@aaa.com)])
    

    然后合并并按子集更改顺序 [] 对于第二个检查成员资格的每一列 isin ,最后将boolena掩码转换为整数。

    cols = list(dfs.keys())
    df = pd.concat({k: v.iloc[:, 0] for k, v in dfs.items()}, axis=1)[cols]
    
    df.iloc[:, 1:] = df.iloc[:, 1:].apply(lambda x: df.iloc[:, 0].isin(x)).astype(int)
    print (df)
      ReceivedEmail OpenedEmail ClickedURL
    0  aaaa@aaa.com           1          1
    1  bbbb@aaa.com           0          0
    2  cccc@aaa.com           0          0
    3  dddd@aaa.com           1          0
    4  eeee@aaa.com           0          0
    5  ffff@aaa.com           0          0
    6  gggg@aaa.com           1          0
    7  rrrr@aaa.com           1          1
    8  qqqq@aaa.com           0          0
    9  oooo@aaa.com           1          0