我有一个DataFrame
力 - 位移数据.位移数组已设置为DataFrame
索引,列是不同测试的各种力曲线.
如何计算完成的工作("曲线下面积")?
我看着numpy.trapz
哪些似乎做了我需要的东西,但我认为我可以避免像这样循环遍历每一列:
import numpy as np import pandas as pd forces = pd.read_csv(...) work_done = {} for col in forces.columns: work_done[col] = np.trapz(forces.loc[col], forces.index))
我希望DataFrame
在曲线下创建一个新的区域而不是a dict
,并且认为DataFrame.apply()
或某些东西可能是合适的但不知道从哪里开始寻找.
简而言之:
我可以避免循环吗?
我DataFrame
可以直接创建一项工作吗?
在此先感谢您的帮助.
您可以通过将整个传递DataFrame
给np.trapz
并指定axis=
参数来对此进行矢量化,例如:
import numpy as np import pandas as pd # some random input data gen = np.random.RandomState(0) x = gen.randn(100, 10) names = [chr(97 + i) for i in range(10)] forces = pd.DataFrame(x, columns=names) # vectorized version wrk = np.trapz(forces, x=forces.index, axis=0) work_done = pd.DataFrame(wrk[None, :], columns=forces.columns) # non-vectorized version for comparison work_done2 = {} for col in forces.columns: work_done2.update({col:np.trapz(forces.loc[:, col], forces.index)})
这些给出以下输出:
from pprint import pprint pprint(work_done.T) # 0 # a -24.331560 # b -10.347663 # c 4.662212 # d -12.536040 # e -10.276861 # f 3.406740 # g -3.712674 # h -9.508454 # i -1.044931 # j 15.165782 pprint(work_done2) # {'a': -24.331559643023006, # 'b': -10.347663159421426, # 'c': 4.6622123535050459, # 'd': -12.536039649161403, # 'e': -10.276861220217308, # 'f': 3.4067399176289994, # 'g': -3.7126739591045541, # 'h': -9.5084536839888187, # 'i': -1.0449311137294459, # 'j': 15.165781517623724}
您的原始示例还有其他一些问题.col
是列名而不是行索引,因此需要索引数据帧的第二维(即.loc[:, col]
而不是.loc[col]
).此外,最后一行有一个额外的尾随括号.
您可能还产生输出DataFrame
直接由.apply
荷兰国际集团np.trapz
到每一列,例如:
work_done = forces.apply(np.trapz, axis=0, args=(forces.index,))
但是,这并不是真正"正确"的矢量化 - 您仍然np.trapz
在每个列上单独调用.你可以通过比较.apply
版本的速度与np.trapz
直接调用来看到这一点:
In [1]: %timeit forces.apply(np.trapz, axis=0, args=(forces.index,)) 1000 loops, best of 3: 582 µs per loop In [2]: %timeit np.trapz(forces, x=forces.index, axis=0) The slowest run took 6.04 times longer than the fastest. This could mean that an intermediate result is being cached 10000 loops, best of 3: 53.4 µs per loop
这不是一个完全公平的比较,因为第二个版本排除了DataFrame
从输出numpy数组构造的额外时间,但是这应该仍然小于执行实际集成所花费的时间差.