首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让这个for循环更快?

如何让这个for循环更快?
EN

Stack Overflow用户
提问于 2019-03-04 23:43:13
回答 3查看 213关注 0票数 2

我知道与其他语言相比,python循环本身相对较慢,但当使用正确的函数时,它们会变得更快。我有一个名为"acoustics“的熊猫数据帧,它包含1000多万行:

代码语言:javascript
复制
print(acoustics)
                        timestamp            c0  rowIndex
0        2016-01-01T00:00:12.000Z  13931.500000   8158791
1        2016-01-01T00:00:30.000Z  14084.099609   8158792
2        2016-01-01T00:00:48.000Z  13603.400391   8158793
3        2016-01-01T00:01:06.000Z  13977.299805   8158794
4        2016-01-01T00:01:24.000Z  13611.000000   8158795
5        2016-01-01T00:02:18.000Z  13695.000000   8158796
6        2016-01-01T00:02:36.000Z  13809.400391   8158797
7        2016-01-01T00:02:54.000Z  13756.000000   8158798

下面是我写的代码:

代码语言:javascript
复制
acoustics = pd.read_csv("AccousticSandDetector.csv", skiprows=[1])
weights = [1/9, 1/18, 1/27, 1/36, 1/54]
sumWeights = np.sum(weights)
deltaAc = []
for i in range(5, len(acoustics)):
    time = acoustics.iloc[i]['timestamp']
    sum = 0
    for c in range(5):
        sum += (weights[c]/sumWeights)*(acoustics.iloc[i]['c0']-acoustics.iloc[i-c]['c0'])
    print("Row " + str(i) + " of " + str(len(acoustics)) + " is iterated")
    deltaAc.append([time, sum])

deltaAc = pd.DataFrame(deltaAc)

这需要大量的时间,我怎么才能让它更快呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-05 01:30:47

您可以使用pandas中的diff并为数组中的每一行创建所有差异,然后与weigths相乘,最后在轴1上使用sum,例如:

代码语言:javascript
复制
deltaAc = pd.DataFrame({'timestamp': acoustics.loc[5:, 'timestamp'], 
                       'summation': (np.array([acoustics.c0.diff(i) for i in range(5) ]).T[5:]
                                               *np.array(weights)).sum(1)/sumWeights})

你得到的值和我用你的代码得到的值是一样的:

代码语言:javascript
复制
print (deltaAc)
                  timestamp  summation
5  2016-01-01T00:02:18.000Z -41.799986
6  2016-01-01T00:02:36.000Z  51.418728
7  2016-01-01T00:02:54.000Z  -3.111184
票数 1
EN

Stack Overflow用户

发布于 2019-03-05 00:07:14

首先是优化,weights[c]/sumWeights可以在循环之外完成。

代码语言:javascript
复制
weights_array = np.array([1/9, 1/18, 1/27, 1/36, 1/54])
sumWeights = np.sum(weights_array)
tmp = weights_array / sumWeights
...
        sum += tmp[c]*...

我对pandas并不熟悉,但是如果你能把你的列提取成1Dnumpy数组,那对你来说就太好了。它可能看起来像这样:

代码语言:javascript
复制
# next lines to be tested, or find the correct way of extracting the column
c0_column = acoustics[['c0']].values
time_column = acoustics[['times']].values
...
sum = numpy.zeros(shape=(len(acoustics)-5,))
delta_ac = []
for c in range(5):
    sum += tmp[c]*(c0_column[5:]-c0_column[5-c:len(acoustics)-c])

for i in range(len(acoustics)-5):
    deltaAc.append([time[5+i], sum[i])
票数 0
EN

Stack Overflow用户

发布于 2019-03-05 07:32:29

Dataframe有一个很好的方法rolling来构造和应用窗口转换;所以,你根本不需要循环:

代码语言:javascript
复制
# df is your data frame
window_size = 5
weights = pd.np.array([1/9, 1/18, 1/27, 1/36, 1/54])
weights /= weights.sum()
df.loc[:,'deltaAc'] = df.loc[:, 'c0'].rolling(window_size).apply(lambda x: ((x[-1] - x)*weights).sum())
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54986640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档