将矩阵与列向量进行比较

Zan*_*nam 5 python numpy multidimensional-array pandas numpy-ndarray

下面的数组'A'和向量'B'是pandas数据帧的一部分.

我有一大堆A形式:

28  39  52
77  80  66
7   18  24
9   97  68
Run Code Online (Sandbox Code Playgroud)

我有一个B形式的矢量:

32
5
42
17
Run Code Online (Sandbox Code Playgroud)

如何比较A的每一列与B的python.I我试图获得A <B比较的真/假值以获得以下结果:

TRUE    FALSE   FALSE
FALSE   FALSE   FALSE
TRUE    TRUE    TRUE
TRUE    FALSE   FALSE
Run Code Online (Sandbox Code Playgroud)

我可以做列表理解语法,但有更好的方法来解决这个问题.我的阵列A和B非常大.

piR*_*red 15

考虑pd.DataFramepd.Series,AB

A = pd.DataFrame([
        [28, 39, 52],
        [77, 80, 66],
        [7, 18, 24],
        [9, 97, 68]
    ])

B = pd.Series([32, 5, 42, 17])
Run Code Online (Sandbox Code Playgroud)

pandas

默认情况下,当您将a pd.DataFrame与a 进行比较时pd.Series,pandas 会将系列中的每个索引值与数据帧的列名对齐.这是您使用时发生的情况A < B.在这种情况下,数据框中有4行,系列中有4个元素,因此我假设您要将系列的索引值与数据帧的索引值对齐.要指定要对齐的轴,需要使用比较方法而不是运算符.那是因为当您使用该方法时,您可以使用该axis参数并指定您想要的axis=0而不是默认值axis=1.

A.lt(B, axis=0)

       0      1      2
0   True  False  False
1  False  False  False
2   True   True   True
3   True  False  False
Run Code Online (Sandbox Code Playgroud)

我经常把它写成 A.lt(B, 0)


numpy

在numpy中,你还必须注意数组的维度,假设这些位置已经排成一行.该位置被照顾,如果他们来自同一个数据帧的.

print(A.values)

[[28 39 52]
 [77 80 66]
 [ 7 18 24]
 [ 9 97 68]]

print(B.values)

[32  5 42 17]
Run Code Online (Sandbox Code Playgroud)

注意,它B是一维数组,而A是二维数组.为了比较B沿着A我们需要重塑B成二维数组的行.最明显的方法是使用reshape

print(A.values < B.values.reshape(4, 1))

[[ True False False]
 [False False False]
 [ True  True  True]
 [ True False False]]
Run Code Online (Sandbox Code Playgroud)

但是,这些是您通常会看到其他人进行相同重塑的方式

A.values < B.values.reshape(-1, 1)
Run Code Online (Sandbox Code Playgroud)

要么

A.values < B.values[:, None]
Run Code Online (Sandbox Code Playgroud)

定时回测

为了掌握这些比较的速度,我构建了以下后面的测试.

def pd_cmp(df, s):
    return df.lt(s, 0)

def np_cmp_a2a(df, s):
    """To get an apples to apples comparison
    I return the same thing in both functions"""
    return pd.DataFrame(
        df.values < s.values[:, None],
        df.index, df.columns
    )

def np_cmp_a2o(df, s):
    """To get an apples to oranges comparison
    I return a numpy array"""
    return df.values < s.values[:, None]


results = pd.DataFrame(
    index=pd.Index([10, 1000, 100000], name='group size'),
    columns=pd.Index(['pd_cmp', 'np_cmp_a2a', 'np_cmp_a2o'], name='method'),
)

from timeit import timeit

for i in results.index:
    df = pd.concat([A] * i, ignore_index=True)
    s = pd.concat([B] * i, ignore_index=True)
    for j in results.columns:
        results.set_value(
            i, j,
            timeit(
                '{}(df, s)'.format(j),
                'from __main__ import {}, df, s'.format(j),
                number=100
            )
        )

results.plot()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我可以得出结论,numpy基于解决方案的速度更快,但并不是那么多.它们都是相同的.