比较向量数组中的向量

时间:2015-11-14 13:59:12

标签: python arrays numpy multidimensional-array

我非常困难,而且我所问过的每个蟒蛇似乎都无法提供帮助。

我使用vstack在循环中创建一个向量数组,如下所示:

Corr = np.vstack((Corr, S))

我需要删除重复的向量,以便它是一个独特的向量数组,并比较所有这些向量。

我知道这种比较可以在列表中完成,但我还没有找到将完整向量附加到列表的方法。

这是结果(我标记了具有唯一字母的唯一向量):

Corr = [[ 0.  0.  0.  0. -2.  4.  4.  2.  2.] #a
 [-4. -4. -4. -4.  2.  4.  4.  2.  2.]#b
 [-4.  0.  0.  4. -2.  0.  0. -2.  2.]#c
 [ 0. -4. -4.  0.  2.  0.  0. -2.  2.]#d
 [ 0. -4.  4.  0. -2.  0.  0.  2. -2.]#e
 [-4.  0.  0. -4.  2.  0.  0.  2. -2.]#f
 [-4. -4.  4.  4. -2.  4. -4. -2. -2.]#g
 [ 0.  0.  0.  0.  2.  4. -4. -2. -2.]#h
 [ 0.  4. -4.  0. -2.  0.  0.  2. -2.]#i
 [-4.  0.  0. -4.  2.  0.  0.  2. -2.]#f
 [-4.  4. -4.  4. -2. -4.  4. -2. -2.]#j
 [ 0.  0.  0.  0.  2. -4.  4. -2. -2.]#k
 [ 0.  0.  0.  0. -2. -4. -4.  2.  2.]#l
 [-4.  4.  4. -4.  2. -4. -4.  2.  2.]#m
 [-4.  0.  0.  4. -2.  0.  0. -2.  2.]#n
 [ 0.  4.  4.  0.  2.  0.  0. -2.  2.]#o
 [ 4.  0.  0. -4. -2.  0.  0. -2.  2.]#c
 [ 0. -4. -4.  0.  2.  0.  0. -2.  2.]#d
 [ 0.  0.  0.  0. -2. -4. -4.  2.  2.]#p
 [ 4. -4. -4.  4.  2. -4. -4.  2.  2.]#q
 [ 4. -4.  4. -4. -2. -4.  4. -2. -2.]#r
 [ 0.  0.  0.  0.  2. -4.  4. -2. -2.]#k
 [ 0. -4.  4.  0. -2.  0.  0.  2. -2.]#e
 [ 4.  0.  0.  4.  2.  0.  0.  2. -2.]#s
 [ 4.  4. -4. -4. -2.  4. -4. -2. -2.]#t
 [ 0.  0.  0.  0.  2.  4. -4. -2. -2.]#h
 [ 0.  4. -4.  0. -2.  0.  0.  2. -2.]#i
 [ 4.  0.  0.  4.  2.  0.  0.  2. -2.]#s
 [ 4.  0.  0. -4. -2.  0.  0. -2.  2.]#u
 [ 0.  4.  4.  0.  2.  0.  0. -2.  2.]#o
 [ 0.  0.  0.  0. -2.  4.  4.  2.  2.]]#a

我不知道为什么vstack正在添加句号而不是逗号(在循环中,每个向量S在我单独打印时都有逗号!)。

我需要最终结果是一个独特的向量数组(所以在这种情况下,它将是向量a-u,即21个向量)。

3 个答案:

答案 0 :(得分:2)

如果将向量转换为元组,可以将它们放在set中,这将自动丢弃重复项。例如:

unique_vectors = set(map(tuple, Corr))

array_of_unique_vectors = np.array(list(unique_vectors))

编辑:我很好奇,所以我在这里快速对三个提议的解决方案进行了基准测试。结果与返回元素的顺序相同,并且看起来Pandas drop_duplicates方法优于其他方法。

import numpy as np
import pandas as pd

def unique_set(a):
    return np.vstack(set(map(tuple, a)))

def unique_numpy(a):
    a = np.ascontiguousarray(a)
    view = a.view(np.dtype(('void', a.itemsize * a.shape[1])))
    unique = np.unique(view)
    return unique.view(a.dtype).reshape(-1, a.shape[1])

def unique_pandas(a):
    return pd.DataFrame(a).drop_duplicates().values

a = np.random.randint(0, 5, (100000, 5))

%timeit unique_set(a)
10 loops, best of 3: 183 ms per loop

%timeit unique_numpy(a)
10 loops, best of 3: 43.1 ms per loop

%timeit unique_pandas(a)
100 loops, best of 3: 10.3 ms per loop

答案 1 :(得分:2)

这是一个避免数据重复并且不需要像Pandas这样的外部软件包的答案:

$oConnection = \Propel::getConnection();
    $oConnection->beginTransaction();
    for ( $i = 1; $i <= 4; $i++ )
    {
        $oClient = new Client();
        $aData   = array(
            'companyname' => 'company' . $i,
            'contactname' => 'contact' . $i,
            'mail'        => 'mail' . $i . '@hotmail.com',
            'phone'       => '12345678',
            'active'      => true
        );
        $oClient->fromArray($aData, \BasePeer::TYPE_FIELDNAME);
        $oClient->save($oConnection);
        for ( $i = 1; $i <= 4; $i++ )
        {
            $oUser = new User();
            $aData = array(
                'client_id' => $oClient->getId(),
                'firstname'    => 'firstname' . $i,
                'lastname'     => 'lastname' . $i,
                'mail'         => 'mail' . $i . '@hotmail.com',
            );
            $oUser->fromArray($aData, \BasePeer::TYPE_FIELDNAME);
            $oUser->save($oConnection);
        }
    }
    $oConnection->commit();

我发现它比我之前提出的set-of-tuple解决方案快5倍。

答案 2 :(得分:0)

Pandas可以直接解决您的问题 - drop_duplicates功能:

http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.drop_duplicates.html