【问题标题】:Concatenating arrays according to a column [closed]根据列连接数组[关闭]
【发布时间】:2017-01-16 16:19:38
【问题描述】:

我在 python 中有一个二维数组的列表。对于每个二维数组,最后一列表示一个 ID。现在我想根据 ID(最后一列)加入(可能是 numpy)数组的行。

因此,例如 ID 为 1 的行应该被连接起来。每个 ID 在每个数组中仅出现一次。此外,ID(最后一列)以及倒数第二列只能写在串联数组的最后(即只写一次)。

如何做到这一点?

【问题讨论】:

标签: python arrays numpy


【解决方案1】:

Pandas 有一个很好的 join 方法来处理这个角色。如果您的 id 列是您的 DataFrame 的索引,则最容易使用。假设您的二维数组中有两个是adatabdata,它们对应的ID 是a_idsb_ids。 (如果您只处理整数数据集,并且您的 id 也是整数,它们可以进入 numpy 数组的最后一列。但通常 numpy 处理浮点值,并且 id 通常是字符串而不是整数。在任何一个中在这些常见情况中,最好甚至有必要保持 id 分开,因为 numpy 数组是同质的。)

import pandas as pd

a = pd.DataFrame(adata, index=a_ids)
b = pd.DataFrame(bdata, index=b_ids)

现在你有类似的东西:

加入:

ab = a.join(b, lsuffix='a', rsuffix='b', how='outer')

产量:

这是一个外连接,意味着它返回所有记录的联合,包括 id 仅出现在一个或另一个数据集中的情况。如果您只想在两个输入上匹配(或者如果您的所有数据集都有相同的 id),您可以使用 how='inner' 进行更紧密的交叉连接。

如果你想要一个 numpy 数组而不是 DataFrame,这很简单:

ab.values

产量:

array([[-0.68185189,  2.06517757,  0.49309249,  0.56342363],
       [ 0.18518231, -2.93460494,         nan,         nan],
       [ 0.06447249, -0.30244753,  2.46605889, -0.28043202],
       [ 0.62137062,  0.10228747, -0.21668058, -1.07091799],
       [-0.37247196, -1.5782334 ,         nan,         nan],
       [-1.0523353 , -0.52960419,         nan,         nan],
       [ 0.13638979,  0.92173315,         nan,         nan]])

对于连接索引:

ab.index.values 

给予:

array([1001, 1002, 1003, 1004, 1005, 1006, 1007])

因此,尽管您已熟悉 Pandas 并从其高级连接操作中受益(即使您的数据集大小不同,该操作也有效,但包含的 id 并不完全相同,即使 id 的顺序不同) ,如果你想使用这些值,你就可以回到 NumPy 值中。

最后注意,如果您将 NumPy 用于整数值,那么您的 id 已经作为每个数据集中的最后一列嵌入,只需调整 DataFrame 构造函数以获取如下数据:

a = pd.DataFrame(adata[:, :-1], index=adata[:, -1])
b = pd.DataFrame(bdata[:, :-1], index=bdata[:, -1])

                     # data                 ids
                     # ^ all rows           ^ all rows
                     #    ^ all but last col   ^ just last col

【讨论】:

    【解决方案2】:

    这是一个使用pandas 的最小示例,因为最初没有提供数据或代码:

    import numpy as np
    import pandas as pd
    
    # let the last column in these 2-d arrays be the "ID" column
    arr1 = np.array([[0,0,1,1,1], [0,1,0,0,2], [1,1,1,2,3]])
    arr2 = np.array([[1,1,1,1,1], [2,1,0,0,2], [2,2,1,2,3]])
    
    df1 = pd.DataFrame(arr1)
    df2 = pd.DataFrame(arr2)
    
    # Again, a minimal example, but the column at index 4 in these
    # DataFrames is the ID column, so we can merge on 4 to get our result
    result = pd.merge(df1, df2, on = 4)
    

    【讨论】:

      【解决方案3】:

      带有@robot's 样本数据的numpy 版本,使用argsort 按最后一列值收集行:

      In [28]: arr1 = np.array([[0,0,1,1,1], [0,1,0,0,2], [1,1,1,2,3]])
      In [29]: arr2 = np.array([[1,1,1,1,1], [2,1,0,0,2], [2,2,1,2,3]])
      In [30]: arr=np.concatenate((arr1,arr2),axis=0)
      In [31]: arr
      Out[31]: 
      array([[0, 0, 1, 1, 1],
             [0, 1, 0, 0, 2],
             [1, 1, 1, 2, 3],
             [1, 1, 1, 1, 1],
             [2, 1, 0, 0, 2],
             [2, 2, 1, 2, 3]])
      In [32]: idx=np.argsort(arr[:,-1])
      In [33]: idx
      Out[33]: array([0, 3, 1, 4, 2, 5], dtype=int32)
      In [34]: arr[idx,:]
      Out[34]: 
      array([[0, 0, 1, 1, 1],
             [1, 1, 1, 1, 1],
             [0, 1, 0, 0, 2],
             [2, 1, 0, 0, 2],
             [1, 1, 1, 2, 3],
             [2, 2, 1, 2, 3]])
      

      此外,ID(最后一列)以及倒数第二列只能写在串联数组的最后(即只写一次)。

      如果我理解正确的话,这个要求对于numpy 是不可能的。数组每行的列数必须相同。使用pandas,您可以构建多级索引,并且大概使用此ID 作为索引级别。

      我们需要您自己的样本、输入和结果,才能做得更好。

      ================

      我们可以使用np.split 将排序后的数组分解为具有共同最后一列的数组。我手动选择了[2,4],但如果您有兴趣,可以从数据中得出。

      In [39]: np.split(arr[idx,:],[2,4])
      Out[39]: 
      [array([[0, 0, 1, 1, 1],
              [1, 1, 1, 1, 1]]), 
       array([[0, 1, 0, 0, 2],
              [2, 1, 0, 0, 2]]), 
       array([[1, 1, 1, 2, 3],
              [2, 2, 1, 2, 3]])]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-19
        • 2013-10-16
        • 1970-01-01
        • 1970-01-01
        • 2017-07-18
        • 2011-12-29
        • 2016-07-22
        相关资源
        最近更新 更多