【问题标题】:Broadcasting logical operators along a different axis沿不同轴广播逻辑运算符
【发布时间】:2016-08-16 10:50:07
【问题描述】:

我有一个 DataFrame 和一个系列:

np.random.seed(0)
df = pd.DataFrame(np.random.binomial(1, 0.3, (5, 4)).astype(bool))
ser = pd.Series(np.random.binomial(1, 0.3, 5).astype(bool))
df
出去:
       0 1 2 3
0 假 真 假 假
1 假 假 假 真
2 真假真假
3 假 真 假 假
4 假 真 真 真

SER
出去:
0 真
1 对
2 错误
3 真
4 错误
数据类型:布尔

我想逐行比较每一列与系列,看看这两个元素是否为真。结果应该是:

 0 1 2 3
0 假 真 假 假
1 假 假 假 真
2 假 假 假 假
3 假 真 假 假
4 假 假 假 假

我可以使用df.mul(ser, axis=0) 执行此操作,但会引发警告:

UserWarning:在 Python 空间中进行评估,因为 '*' 运算符是 numexpr 不支持 bool dtype,请改用 '&'

我猜这会减慢操作速度。有其他选择吗?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    由于这个计算是基于数组的(不需要对齐索引标签), 您可以使用 NumPy 数组和 NumPy 广播来计算:

    np.logical_and(df.values, ser.values[:, None])
    

    以下是几个备选方案的速度比较:

    import numpy as np
    import pandas as pd
    
    N, M = 500, 400
    np.random.seed(0)
    df = pd.DataFrame(np.random.binomial(1, 0.3, (N, M)).astype(bool))
    ser = pd.Series(np.random.binomial(1, 0.3, N).astype(bool))
    

    In [60]: %timeit pd.DataFrame(np.logical_and(df.values, ser.values[:, None]), columns=df.columns, index=df.index)
    10000 loops, best of 3: 93.4 µs per loop
    
    In [51]: %timeit pd.DataFrame(df.values * ser.values[:,None], columns=df.columns, index=df.index)
    10000 loops, best of 3: 94.4 µs per loop
    
    In [47]: %timeit df.mul(ser, axis=0)
    UserWarning: evaluating in Python space because the '*' operator is not supported by numexpr for the bool dtype, use '&' instead
    10000 loops, best of 3: 166 µs per loop
    
    In [46]: %timeit df.apply(lambda x: x & ser)
    10 loops, best of 3: 135 ms per loop
    

    【讨论】:

      猜你喜欢
      • 2018-05-22
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 2017-09-08
      • 2011-09-23
      相关资源
      最近更新 更多