【问题标题】:Create an array of arrays from a dataframe with multiple multivariate time series in Python在 Python 中从具有多个多元时间序列的数据帧创建数组数组
【发布时间】:2020-09-29 07:03:22
【问题描述】:

我需要从数据框创建一个数组数组:

HR    sBP   dBP  T     ID
101   51    81   37.1  P1.1
102   52    82   37.2  P1.1
103   53    83   37.3  P1.1
104   54    84   37.4  P1.1
105   55    85   37.5  P1.1
210   65    90   36.1  P1.2
210   65    90   36.2  P1.2
210   65    90   36.3  P1.2
210   65    90   36.4  P1.2
210   65    90   36.5  P1.2
...
100   50    75   37    Pm.n
100   50    75   37    Pm.n
...
100   50    60   37.0  P1500.6
100   50    60   37.0  P1500.6
100   50    60   37.0  P1500.6
100   50    60   37.0  P1500.6
100   50    60   37.0  P1500.6

其中每个块是一个多元时间序列,其中 HR、sBP、dBP 和 T° 作为变量,ID 变量是来自每个患者的每个数据子序列的标签。每个患者的块的长度是可变的。 我需要得到一个这样的数组:

array([[[101,    51,    81,    37.1],
        [102,    52,    82,    37.2],
        [103,    53,    83,    37.2],
        [104,    54,    84,    37.2],
        [105,    55,    85,    37.2]],

       [[210,    65,    90,    36.1],
        [210,    65,    90,    36.2],
        [210,    65,    90,    36.3],
        [210,    65,    90,    36.4],
        [210,    65,    90,    36.5]],

      ...

       [[100,    50,    60,    37.0], 
        [100,    50,    60,    37.0],
        [100,    50,    60,    37.0],  
        [100,    50,    60,    37.0],
        [100,    50,    60,    37.0]]])

array.shape = (number of unique IDs, length of arrays, number of dimensions)

我的代码如下所示:

df_grp = df.groupby('ID')

for name, gp in df_grp:
    if name == 'P1.1':
        arr = gp.drop(columns = ['ID']).to_numpy().reshape(-1,4)  

    else:
        temp_arr = gp.drop(columns = ['ID']).to_numpy().reshape(-1,4)  
        arr = np.append(arr, temp_arr, axis=0)

但它给了我一个这样的数组

array ([[101,    51,    81,    37.1],
        [102,    52,    82,    37.2],
        [103,    53,    83,    37.2],
        [104,    54,    84,    37.2],
        [105,    55,    85,    37.2],
        [210,    65,    90,    36.1],
        [210,    65,    90,    36.2],
        [210,    65,    90,    36.3],
        [210,    65,    90,    36.4],
        [210,    65,    90,    36.5]],

      ...

        [100,    50,    60,    37.0], 
        [100,    50,    60,    37.0],
        [100,    50,    60,    37.0],  
        [100,    50,    60,    37.0],
        [100,    50,    60,    37.0]])

array.shape = (number of rows in df, number of dimensions)。不管有没有reshape,结果都是一样的,squeeze也是一样。 我需要上述格式的数组,以便可以在 tslearn 包中使用它进行多变量时间序列聚类。 非常感谢任何帮助。

【问题讨论】:

    标签: python pandas numpy time-series


    【解决方案1】:

    我想你正在寻找这个:

    arr = df.set_index('ID').groupby('ID').apply(pd.DataFrame.to_numpy).to_numpy()
    

    与您的解决方案类似,首先 groupby 然后使用 to_numpy 将它们转换为数组。请注意,如果您的数组具有不同的形状(即不同的 ID 长度),则不能有非矩形 numpy 数组。因此,此代码返回您要查找的数组数组。

    输出:

    [array([[101. ,  51. ,  81. ,  37.1],
            [102. ,  52. ,  82. ,  37.2],
            [103. ,  53. ,  83. ,  37.3],
            [104. ,  54. ,  84. ,  37.4],
            [105. ,  55. ,  85. ,  37.5]])
      array([[210. ,  65. ,  90. ,  36.1],
            [210. ,  65. ,  90. ,  36.2],
            [210. ,  65. ,  90. ,  36.3],
            [210. ,  65. ,  90. ,  36.4],
            [210. ,  65. ,  90. ,  36.5]])
     ...
      array([[100.,  50.,  75.,  37.],
            [100.,  50.,  75.,  37.]])
     ...
      array([[100.,  50.,  60.,  37.],
            [100.,  50.,  60.,  37.],
            [100.,  50.,  60.,  37.],
            [100.,  50.,  60.,  37.],
            [100.,  50.,  60.,  37.]])]
    

    如果所有'ID's的行数相同,则可以将上面的numpy数组arr堆叠得到一个数组:

    np.stack(arr)
    
    [[[101.   51.   81.   37.1]
      [102.   52.   82.   37.2]
      [103.   53.   83.   37.3]
      [104.   54.   84.   37.4]
      [105.   55.   85.   37.5]]
    
     [[210.   65.   90.   36.1]
      [210.   65.   90.   36.2]
      [210.   65.   90.   36.3]
      [210.   65.   90.   36.4]
      [210.   65.   90.   36.5]]
    ...
     [[100.   50.   60.   37. ]
      [100.   50.   60.   37. ]
      [100.   50.   60.   37. ]
      [100.   50.   60.   37. ]
      [100.   50.   60.   37. ]]]
    

    【讨论】:

    • 谢谢,但我从代码的 .apply(pd.DataFrame.to_numpy) 部分收到错误 TypeError: 'deep' is an invalid keyword argument for copy()。请注意,ID 的长度可能会有所不同。
    • @JuanWeber 当我发布输出时,它适用于您在问题中提供的数据框示例。你的 pandas 和 numpy 版本是最新的吗?如果没有,请尝试更新它们。如果不起作用,请提供更多错误信息,以便我们提供更好的帮助。谢谢你。至于不同长度的ID,代码处理。这就是为什么该行为您提供解释的数组数组的原因。
    • 谢谢,更新 pandas 和 numpy 修复了错误。结果数组具有shape = (number of unique IDs, ),并且该数组被 tslearn 接受。但我不确定这是否是预期的行为。你认为有可能得到我一开始发布的形状吗? shape=(n° unique IDs, ??, n° of dimensions) ?我不知道它会在数组长度中显示什么大小。
    • 如果每个 ID 的行数不同,Numpy 不能将数组列表/数组转换为所需形状的单个数组。 (如果它们相同,请使用发布的np.stack(arr) 将其转换为单个数组)。换句话说,你的数组必须是矩形的。至于 tslearn,我没有这方面的专业知识(也许你可以发布一个关于它的新问题)。请查看stackoverflow.com/help/someone-answers 了解如何接受答案,欢迎来到 SO。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 2017-11-19
    • 1970-01-01
    • 2019-12-22
    相关资源
    最近更新 更多