【问题标题】:Doing math within a column of a dataframe or numpy array在数据框或 numpy 数组的列中进行数学运算
【发布时间】:2020-12-23 10:38:45
【问题描述】:

我有一些数据需要进行简单的数学运算,但它们都在同一列中。这是我的数据可能的样子

我需要执行 (A4+A5)-(A2+A3) 之类的操作,然后在每一行上继续该模式。例如,我的公式类似于 (A5+A6)-(A3+A4)。我一直在考虑如何做到这一点几乎一个星期,但我无法弄清楚。解决此问题的最佳方法是什么?我认为我最好的选择是转置数据,然后从那里使用它?

谢谢

编辑:好的,我想出了一些我认为可行的方法,但我不完全确定我的想法是正确的。这是一个代码sn-p。假设上述数据在一个从索引 0 开始的 numpy 数组中,这可以完成工作吗?

for x in range(len(list24)):
try:
    filt = ((list24[x+2]+list24[x+3])-(list24[x]+list24[x+1]))
    fraser.append(filt)
except IndexError:
    pass

【问题讨论】:

  • 你的预期输出是什么?
  • 您始终可以为中间步骤创建额外的列。对不同行的内容使用 shift()。
  • (df[5:-1]+df[6:])-(df[3:-3]+df[4:-2])?
  • 我的预期输出将是输出值的数据框中的一个新列。

标签: python pandas numpy indexing slice


【解决方案1】:

好的,这行得通。我将这些值变成了一个 numpy 数组并执行了以下操作

fraser = []
      for x in range(len(list24)):
    try:
        filt = ((list24[x+2]+list24[x+3])-(list24[x]+list24[x+1]))
        fraser.append(filt)
    except IndexError:
        pass

索引错误是因为最终会到达计算超出索引的地步

【讨论】:

    【解决方案2】:

    对我来说听起来像是卷积。 Scipy 是快速卷积的最佳选择。在您的情况下,您想乘以 [-1, -1, 1, 1] 这意味着列表中的每个元素都与权重相乘并相加 [-1,-1,1,1] 即:-1 * l[x] -1 * l[x+1] +1 * l[x+2] +1 * l[x+3] 对于每个 x。

    这就是卷积的作用。它一直用于信号处理(有限响应滤波器)和图像处理(模糊/锐化)。

    scipy convolution

    我测试过了。结果正是您的代码所做的,并且对于大型列表来说要快得多。在包含 10000 个元素的列表中,scipy 版本需要 291 µs,而您的代码需要 115 ms。速度提高了 400 倍。 (对于小型列表,您的代码更快)。

    有一个列表: l = [5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8]

    你会的:

    >>> from scipy.signal import convolve
    
    >>> f = [1, 1, -1, -1]  # the filter needs to be written backwards due to convention so instead of [-1,-1,1,1] -> [1,1,-1,-1]
    >>> c = convolve(l, f, mode='valid')
    
    >>> c
    array([4,  0,  -4,  0, 4,  0,  -4,  0, 4,  0,  -4,  0, 4])
    

    vs 你的代码:

    >>> c = []
    >>> for x in range(len(l)):
    ...    try:
    ...        filt = ((l[x+2]+l[x+3])-(l[x]+l[x+1]))
    ...        c.append(filt)
    ...    except IndexError:
    ...        pass
    
    >>> c
    [4, 0, -4, 0, 4, 0, -4, 0, 4, 0, -4, 0, 4]
    

    哦。并从数组 c 中获取一个列表,您可以:

    >>> import numpy as np
    >>> c = c.tolist()
    >>> c
    
    [4, 0, -4, 0, 4, 0, -4, 0, 4, 0, -4, 0, 4]
    

    更新:我对此做了一些时间测试。我还发现有一个 numpy 实现。那一个实际上比 scipy 快,尤其是对于很少的样本。 Scipy 在 40 个样本左右更快。

    【讨论】:

    • 这正是我所需要的。谢谢,我不知道它有一个名字,那会让我的生活更轻松。如果您知道那是什么,我正在对 VLF 数据应用 Fraser 过滤器。我猜它只是一个卷积过滤器。
    • 没问题!确保像我在代码中那样向后应用过滤器。由于惯例,过滤器需要向后给予卷积函数(无处不在,不仅仅是python)。另外,我进行了一些速度测试。事实证明,您的解决方案在不到 1000 分的情况下更快。 scipy 函数有一些开销。
    • 哦,很高兴知道。我主要将其应用于 20 到 100 点的数据集。我只会根据数据的长度做一个 if 语句,它应该可以解决性能问题,以防其他人想要使用它。
    • 我进行了速度测试,请参阅我的更新评论。 numpy 有另一个版本,对于 10 多个数据点,它实际上比你的要快。对于 30 多个数据点,Scipy 速度更快。
    猜你喜欢
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多