使用Pandas的GroupBy函数(以及其他建议的方法)为SVM创建特征(行)向量

我正在尝试为SVM分类器创建堆叠的特征向量。我所有的数据都存储在一个大型矩阵中。手头的问题是一个多类分类问题,因此我需要使用多索引进行分组。

以下是我试图实现的一个玩具示例。

N = 4col_ids = string.letters[:N]df = pd.DataFrame(      np.random.randint(10, size=(16,N)),       #np.random.randn(1,N),      columns=['col_{}'.format(letter) for letter in col_ids])test_cols = ['test1','test1','test1','test1','test1','test1','test1','test1','test2','test2','test2','test2','test2','test2','test2','test2']test_iter = [1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2]df.insert(0, 'Activity', test_cols)df.insert(1, 'Iteration', test_iter)

输出结果如下:

   Activity  Iteration  col_A  col_B  col_C  col_D0     test1          1      7      2      9      71     test1          1      9      7      2      72     test1          1      4      4      2      23     test1          1      0      1      0      64     test1          2      3      5      3      35     test1          2      9      5      7      66     test1          2      9      5      8      67     test1          2      9      7      9      18     test2          1      3      2      5      59     test2          1      8      5      9      010    test2          1      8      6      3      911    test2          1      3      9      2      512    test2          2      0      4      4      113    test2          2      7      0      4      614    test2          2      5      4      0      915    test2          2      0      0      5      0

我使用以下groupby来获取适合我应用的分组:

g = df.groupby(["Activity", "Iteration"])                      Activity  Iteration  col_A  col_B  col_C  col_DActivity   Iteration                                                   test1    1         0     test1          1      7      2      9      7                   1     test1          1      9      7      2      7                   2     test1          1      4      4      2      2                   3     test1          1      0      1      0      6         2         4     test1          2      3      5      3      3                   5     test1          2      9      5      7      6                   6     test1          2      9      5      8      6                   7     test1          2      9      7      9      1test2    1         8     test2          1      3      2      5      5                   9     test2          1      8      5      9      0                   10    test2          1      8      6      3      9                   11    test2          1      3      9      2      5         2         12    test2          2      0      4      4      1                   13    test2          2      7      0      4      6                   14    test2          2      5      4      0      9                   15    test2          2      0      0      5      0

现在我想创建特征向量并将它们存储在一个新的DataFrame中,但我希望以一种方式进行操作,即使用两行数据来创建一个特征向量。也就是说,在测试示例中,test1活动执行了两次,每次迭代都有相同的标签,因此在这种情况下它有两个标签:1和2。每个标签应该从两行数据中堆叠起来以创建所需的输出。

test1中,我希望创建四个行向量,使得完整的输出(理想情况下)看起来像这样:

test1 test1 ... test2    7     4         5    2     4         4    9     2         0    7     2         9    9     0         0    7     1         0    2     0         5    7     6         9

我没有写出全部内容,但我希望我的意图是显而易见的。基本上,两行数据变成一个堆叠的行向量(顶部带有标签),这个向量就是一个特征向量。由于我有多个活动,我需要为每个活动创建多个特征向量来训练SVM。对于这个示例,我理想情况下会得到一个包含八个特征行向量的pd.DataFrame,因此数据框将从(16,4)重塑为(8,8)(忽略col_A到col_B之间的实际数据)。

我知道这解释得不是很好,所以如果你需要更多细节,请告诉我,如果你有心情帮助的话。

谢谢。


回答:

你需要向groupby传递一个函数,该函数为最终输出准备数据,然后重新标记列,就像这样:

def f(x):    values = [v for vals in x.values for v in vals[2:]]    return pd.Series(values,name=x.values[0][0])res = df.groupby(["Activity", "Iteration"]).apply(f)res = res.T.rename(columns={(t,i):t for t,i in res.index})print df   print res

在我的测试输出中是这样的:(请注意,数据是随机的!)

   Activity  Iteration  col_A  col_B  col_C  col_D0     test1          1      4      6      5      71     test1          1      5      9      5      42     test1          1      1      8      7      93     test1          1      4      8      1      94     test1          2      4      5      5      65     test1          2      6      3      8      66     test1          2      8      1      1      27     test1          2      5      1      8      18     test2          1      6      3      9      99     test2          1      4      9      9      710    test2          1      5      0      1      311    test2          1      5      8      9      512    test2          2      4      8      3      213    test2          2      8      9      9      414    test2          2      6      1      1      815    test2          2      6      4      4      8    test1  test1  test2  test20       4      4      6      41       6      5      3      82       5      5      9      33       7      6      9      24       5      6      4      85       9      3      9      96       5      8      9      97       4      6      7      48       1      8      5      69       8      1      0      110      7      1      1      111      9      2      3      812      4      5      5      613      8      1      8      414      1      8      9      415      9      1      5      8

每个测试的8个元素的2列稍微复杂一些,但你可以用相同的方式做到这一点:

def g(x):    values = [v for vals in x.values for v in vals[2:]]    return pd.DataFrame({1: values[:N/2*len(x)], 2: values[N/2*len(x):]})res = df.groupby(["Activity", "Iteration"]).apply(g).unstack()r1 = res[1].T.rename(columns={(t,i):t+str(i)+"1" for t,i in res.index})r2 = res[2].T.rename(columns={(t,i):t+str(i)+"2" for t,i in res.index})res = pd.concat([r1,r2],axis=1).sort(axis=1)res = res.rename(columns={t:t[:-2] for t in res.columns})print dfprint res

输出结果如下:

   Activity  Iteration  col_A  col_B  col_C  col_D0     test1          1      0      8      1      71     test1          1      2      0      5      02     test1          1      2      6      6      63     test1          1      5      0      1      44     test1          2      4      5      6      85     test1          2      8      0      1      66     test1          2      6      7      2      47     test1          2      3      2      2      38     test2          1      5      2      1      99     test2          1      8      3      5      910    test2          1      3      7      7      111    test2          1      7      4      5      112    test2          2      9      2      4      013    test2          2      3      1      8      714    test2          2      1      2      7      815    test2          2      4      9      7      0   test1  test1  test1  test1  test2  test2  test2  test20      0      2      4      6      5      3      9      11      8      6      5      7      2      7      2      22      1      6      6      2      1      7      4      73      7      6      8      4      9      1      0      84      2      5      8      3      8      7      3      45      0      0      0      2      3      4      1      96      5      1      1      2      5      5      8      77      0      4      6      3      9      1      7      0

希望这对你有帮助

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注