首页 > 解决方案 > 从长到宽重塑数据集(或用不同的方法来丰富主要数据集的信息)

问题描述

来自 STATA,我在重塑我的数据时遇到了困难,或者我在如何处理 python / ML 问题中的问题时弄错了。

我有多个数据集,我将在这里简要介绍一下:

主数据集,ID 是唯一的,包含每个 ID 的信息,例如姓名、地址、性别……

     +-------------------------------------------+
     |    ID    abc    xyz        ...     ...    |
     |-------------------------------------------|
  1. |    10    5      some       ...     ...    |
  2. |    20    12     strings    ...     ...    |
  3. |    30    3      random     ...     ...    |
  4. |    40    120    info       ...     ...    |
     +-------------------------------------------+

多个附加数据集,ID 不是唯一的,包含有关单个特征的信息,例如拥有的 T 恤的颜色、使用的信用卡供应商……但每个附加信息的不同值数量有限(只有 5 个不同的信用卡供应商或只有 10 种不同颜色可供选择)

     +-----------------+
     |    ID    abc    |
     |-----------------|
  1. |    10    green  |
  2. |    10    red    |
  3. |    10    yellow |
  4. |    20    green  |
  5. |    20    blue   |
  6. |    30    yellow |
     +-----------------+

我想用来自附加数据集的信息来丰富主数据集。我想到的唯一可行的解​​决方案是将附加信息从长改成宽,产生一个唯一的 ID 但附加列,例如 ['colour_red', 'colour_greed', ...] 然后加入主数据集.

     +----------------------------------------+
     |    ID    green   red   yellow   blue   |
     |----------------------------------------|
  1. |    10    green  red    yellow   NaN    |
  2. |    20    green  NaN    NaN      blue   |
  3. |    30    NaN    NaN    yellow   NaN    |
     +----------------------------------------+

     +------------------------------------------------------------------------+
     |    ID    abc    xyz        ...     ...    green   red   yellow   blue  |
     |------------------------------------------------------------------------|
  1. |    10    5      some       ...     ...    green  red    yellow   NaN   |
  2. |    20    12     strings    ...     ...    green  NaN    NaN      blue  |
  3. |    30    3      random     ...     ...    NaN    NaN    yellow   NaN   |
  4. |    40    120    info       ...     ...    NaN    NaN    NaN      NaN   |
     +------------------------------------------------------------------------+

我曾尝试使用 .pivot 但总是以无法与主数据框连接的多索引数据框结束,因为我无法摆脱索引级别或在课程中犯了一些错误。

Thise向我提出了两个问题:

  1. 如何以我用 python 呈现的方式操作数据(熊猫或其他任何套装)
  2. 我走对了吗?或者你会提出一种不同的方法来解决这个问题吗?

我希望我确实遵守社区规则。预先感谢您的帮助!

标签: pythondataframe

解决方案


这是我对这个问题的看法。

我的解决方案完全基于您提出的技术。也许有更好、更优雅的方法来做到这一点。

我使用了您以某种pandas.DataFrame格式呈现的相同数据集。这是称为“主数据集”的df1

df1 = pd.DataFrame([[10, 5, "some"], 
                [20, 12, "strings"], 
                [30, 3, "random"], 
                [40, 120, "info"]], 
               columns=["ID", "abc", "xyz"])

这是这里调用的“附加数据集”df2

df2 = pd.DataFrame([[10, "green"],
                    [10, "red"],
                    [10, "yellow"],
                    [20, "green"],
                    [20, "blue"],
                    [20, "yellow"]],
                  columns = ["ID", "abc"])

第 1 部分:重塑附加信息数据集:

我们首先要重塑形状df2,以将颜色(“蓝色”、“绿色”、“红色”和“黄色”)作为列,并且每一行对应一个 id。

为此,我使用了“one-hot-encoding”技术。在这里阅读更多。这是标准的,我个人更喜欢这种格式,因为我们没有 NaN 值,并且我们不会在列值中不必要地重复列名。

首先,我们使用以下方法获取 one-hot 编码数据帧get_dummies

df2 = pd.get_dummies(df2, prefix="", prefix_sep="")

看起来像:

    ID  blue    green   red     yellow
0   10     0        1     0          0
1   10     0        0     1          0
2   10     0        0     0          1
3   20     0        1     0          0
4   20     1        0     0          0
5   20     0        0     0          1

然后,我们要将数据框分组到“ID”列上,以便一行对应一个 ID。我们可以使用该groupby方法并使用该sum函数组合行来做到这一点。

df2 = df2.groupby("ID").sum().reset_index()

最后,df2(附加数据集)看起来像:

    ID  blue    green   red     yellow
0   10     0        1     1          1
1   20     1        1     0          1

第 2 部分:加入两个数据框。

df3 = pd.merge(left=df1, right=df2, how='left', on="ID", sort=False)
# replace NaN values in the one-hot-encoded vectors with zeros. 
new_columns = ["blue", "green", "red", "yellow"] # One-hot- encoded columns
df3[new_columns] = df3[new_columns].fillna(0).astype(int) # fill na

最后,df3数据框如下所示:

    ID  abc     xyz     blue    green   red     yellow
0   10    5     some       0        1     1          1
1   20   12     strings    1        1     0          1
2   30    3     random     0        0     0          0
3   40  120     info       0        0     0          0

推荐阅读