如何根据特定条件将逐行数据转换为逐列数据

Posted

技术标签:

【中文标题】如何根据特定条件将逐行数据转换为逐列数据【英文标题】:How to covert row wise data to column wise based on certain conditions 【发布时间】:2018-04-12 08:57:06 【问题描述】:

我有一个 excel,其中包含逐行的考试数据(理论、会话、实践等)。我必须将相同的基于 QPCODE 的数据放在单行中。 我的数据是-

 +-------+--------+--------------------+--------------+---------------------------+--------------------+--------------------------+---------------------+-----------+-----------+
    |  id   | qpcode | subject_paper_code | subject_code |       subject_name        | subject_paper_name | subject_paper_short_code | subject_paper_group | min_marks | max_marks |
    +-------+--------+--------------------+--------------+---------------------------+--------------------+--------------------------+---------------------+-----------+-----------+
    | 37790 |  10032 |                  0 | A47          | GEOGRAPHY                 | THEORY             | GEOG1                    | A                   |        21 |        60 |
    | 37791 |        |                  1 | A47          | GEOGRAPHY                 | I.A.(THEORY)       | GE1IA                    | A                   |         0 |        10 |
    | 37792 |        |                  2 | A47          | GEOGRAPHY                 | PRACTICAL          | GE1PR                    | B                   |         9 |        20 |
    | 37793 |        |                  3 | A47          | GEOGRAPHY                 | RECORD             | GE1RC                    | B                   |         0 |        10 |
    | 37794 |  10033 |                  0 | A50          | HINDI (OPT)               | THEORY             | HINO1                    | A                   |        40 |        80 |
    | 37795 |        |                  1 | A50          | HINDI (OPT)               | I.A.(THEORY)       | HI1IA                    | A                   |         0 |        20 |
    | 37796 |  10034 |                  0 | A51          | HISTORY(PRIOR TO 2008-09) | THEORY             | HIST1                    | A                   |        40 |        80 |
    +-------+--------+--------------------+--------------+---------------------------+--------------------+--------------------------+---------------------+-----------+-----------+

我必须将相同的 qpcode 数据放在单行中,以便我可以在单行中为所有 qpcode 获取相同的 qpcode 数据。

+-------+--------+--------------------+--------------+--------------+--------------------+--------------------------+---------------------+-----------+-----------+---------------------------+------------+------------+---------------------------+------------+------------+---------------------------+------------+------------+
|  id   | qpcode | subject_paper_code | subject_code | subject_name | subject_paper_name | subject_paper_short_code | subject_paper_group | min_marks | max_marks | subject_paper_short_code2 | min_marks2 | max_marks2 | subject_paper_short_code3 | min_marks3 | max_marks3 | subject_paper_short_code4 | min_marks4 | max_marks4 |
+-------+--------+--------------------+--------------+--------------+--------------------+--------------------------+---------------------+-----------+-----------+---------------------------+------------+------------+---------------------------+------------+------------+---------------------------+------------+------------+
| 37790 |  10032 |                  0 | A47          | GEOGRAPHY    | THEORY             | GEOG1                    | A                   |        21 |        60 | GE1IA                     |          0 |         10 | GE1PR                     |          9 |         20 | GE1RC                     |          0 |         10 |
+-------+--------+--------------------+--------------+--------------+--------------------+--------------------------+---------------------+-----------+-----------+---------------------------+------------+------------+---------------------------+------------+------------+---------------------------+------------+------------+

【问题讨论】:

【参考方案1】:

使用 VBA 执行此操作更简单。但我想看看是否可以使用数据透视表来完成。所以这是我遵循的四个步骤。

第 1 步:清理数据

    将数据复制到新工作表。

    有一些不必要的列。删除它们:

    身份证 subject_paper_code 主题代码 主题名称 subject_paper_name subject_paper_group

它们在摘要中没有任何用途,而且由于它们与特定记录有关,因此相当不合适。但是,如果您确实想要这些,您可以在之后使用简单的VLOOKUP 来获取它们。

删除这些列后,您将剩下四列。假设这些包含在A:D 列中。

    您需要一个辅助列来替换原来的 qpcode 列,以便试卷代码是连续的并且它们之间没有任何空白单元格。

为此,您可以在 A 列的左侧插入一列(包含 qpcode),将此公式粘贴到 A2 并向下拖动:

=IF(ISBLANK(B2),A1,B2)

这将使每条记录的 qpcodes 重复。

    复制该列并将其粘贴为值。删除每组记录只包含一个代码的原始qpcode 列(B 列)。

您的工作表应如下所示:

╔════════╦══════════════════════════╦═══════════╦═══════════╗
║ qpcode ║ subject_paper_short_code ║ min_marks ║ max_marks ║
╠════════╬══════════════════════════╬═══════════╬═══════════╣
║  10032 ║ GEOG1                    ║        21 ║        60 ║
║  10032 ║ GE1IA                    ║         0 ║        10 ║
║  10032 ║ GE1PR                    ║         9 ║        20 ║
║  10032 ║ GE1RC                    ║         0 ║        10 ║
║  10033 ║ HINO1                    ║        40 ║        80 ║
║  10033 ║ HI1IA                    ║         0 ║        20 ║
║  10034 ║ HIST1                    ║        40 ║        80 ║
╚════════╩══════════════════════════╩═══════════╩═══════════╝

第 2 步:创建数据透视表

    创建数据透视表

    qpcode 拖到行区域

    将这些字段按此顺序一一拖到列区域

    subject_paper_short_code min_marks max_marks

    对您在上一步中放置在“列”区域中的所有三个字段使用以下设置

    点击该字段;选择“字段设置” 在Subtotals & Filters 标签中选择None 转到Layout & Print 选项卡并检查Repeat item labels 选项

注意:仅列区域中的前两项需要应用上一步中的设置。将它们应用于第三个 (max_marks) 没有任何区别。

    也将它们拖到值区域(这些与您在上一步中放置在列区域中的相同):

    subject_paper_short_code min_marks max_marks

    在“汇总值字段依据”设置中选择“计数”选项。这只是为了使最后的清洁部分更容易一些。

第 3 步:处理结果

    复制数据透视表并在新工作表中,使用“选择性粘贴”选项中的“粘贴为值”粘贴它

    从数据透视表的副本中复制列和行标签,并将其粘贴到下方。这是一个屏幕截图,以使其更清晰:

我已将列标题加粗。

    将此公式粘贴到B10,并将其复制到整个范围(在本例中为B10:V12):
=IF(NOT(ISBLANK(B5)),INDIRECT(ADDRESS(MOD(COLUMN()-1,3)+3*(MOD(COLUMN()-1,3)=0),COLUMN())))

为接下来的说明选择此范围。

    再次复制此范围,并将其作为值粘贴(在同一位置)。

    在仍选择范围的情况下,按 Ctrl + H(替换对话框),然后将 FALSE 替换为空格。

    F5,然后选择 Goto Special。然后,选择Blank 单元格选项并按Enter。现在,只会选择范围内的空白单元格。

    Ctrl + -,在弹出的对话框中选择Shift cells left

第 4 步:清理

请注意列标题​​前面的“计数”。选择行并将Count of(包括尾随空格)替换为空白。

Row Label 替换为qpcode

最后会保留一些额外的列。也删除它们。

就是这样。这应该会给你留下你需要的数据。

这是您提供的数据的输出:

╔════════╦══════════════════════════╦═══════════╦═══════════╦══════════════════════════╦═══════════╦═══════════╦══════════════════════════╦═══════════╦═══════════╦══════════════════════════╦═══════════╦═══════════╗
║ qpcode ║ subject_paper_short_code ║ min_marks ║ max_marks ║ subject_paper_short_code ║ min_marks ║ max_marks ║ subject_paper_short_code ║ min_marks ║ max_marks ║ subject_paper_short_code ║ min_marks ║ max_marks ║
╠════════╬══════════════════════════╬═══════════╬═══════════╬══════════════════════════╬═══════════╬═══════════╬══════════════════════════╬═══════════╬═══════════╬══════════════════════════╬═══════════╬═══════════╣
║  10032 ║ GE1IA                    ║         0 ║        10 ║ GE1PR                    ║         9 ║        20 ║ GE1RC                    ║         0 ║        10 ║ GEOG1                    ║        21 ║        60 ║
║  10033 ║ HI1IA                    ║         0 ║        20 ║ HINO1                    ║        40 ║        80 ║                          ║           ║           ║                          ║           ║           ║
║  10034 ║ HIST1                    ║        40 ║        80 ║                          ║           ║           ║                          ║           ║           ║                          ║           ║           ║
╚════════╩══════════════════════════╩═══════════╩═══════════╩══════════════════════════╩═══════════╩═══════════╩══════════════════════════╩═══════════╩═══════════╩══════════════════════════╩═══════════╩═══════════╝

【讨论】:

以上是关于如何根据特定条件将逐行数据转换为逐列数据的主要内容,如果未能解决你的问题,请参考以下文章

将宽数据帧转换为具有特定条件并添加新列的长数据帧

逐列匹配展平R数据帧中的行

如何根据条件将字符串数组转换为结构数组

根据条件转换数据帧的列

pandas 根据条件将数据转换为多步时间序列

检索日期并根据用户时区将其转换为特定时区