首页 > 解决方案 > 在数据框或 numpy 数组的列中进行数学运算

问题描述

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

在此处输入图像描述

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

谢谢

编辑:好的,我想出了一些我认为可行的方法,但我不完全确定我的想法是正确的。这是一个代码片段。假设所述数据位于从索引 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

标签: pythonpandasnumpyindexingslice

解决方案


对我来说听起来像卷积。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 卷积

我测试了它。结果正是您的代码所做的,并且对于大型列表来说要快得多。在包含 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])

与您的代码:

>>> 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 个样本左右更快。 在此处输入图像描述


推荐阅读