python 如何优化双重循环?

2016-01-28 07:10:35 +08:00
 billgreen1

我有一个双重循环耗时比较多,主要可能在检查 index 上面:

from scipy.stats import pearsonr
      # X,Y 是一个字典,每一个 key 对应一个序列 pandas.Series , 序列的元素是 float
      # 难点:序列的 index 可能不一致,比如 X[k1] 这个序列的 index 是 0 到 100 ,
      # Y[k2] 这个序列的 index 是 30 到 130 , X[k1] 和 Y[k2] 这两个序列里面可能有 nan 值。
      # 要求:取出 X[k1] 和 Y[k2] 这两个序列中索引相同的,且不含 nan 值的部分,做相关系数
      result = np.empty((len(X),len(y)))
      for kx in X.keys():
           for ky in Y.keys():
                df = pd.DataFrame({'col1':X[kx], 'col2':Y[ky]}).dropna()  # 耗时几乎都在这上面了 
                result[kx,ky] = pearsonr(df.col1, df.col2)

真正的 pearsonr 并不耗费多少时间,请教该如何优化是好?

4299 次点击
所在节点    Python
6 条回复
yelite
2016-01-28 07:20:45 +08:00
试试看不创建 DataFrame ,用 is_nan 之类的函数生产两个 Bool Series ,然后 and 一下作为 index ,最后应该是 `pearsonr(X[kx][idx], Y[ky][idx])` 这种感觉
fractal314
2016-01-28 07:24:23 +08:00
倒数第二行的计算量是 o(n*n)的。自己写的话,应该是 o(n)的
billgreen1
2016-01-28 07:29:24 +08:00
@yelite 嗯,我目前是这个思路,然后能想到的只有 multiprocessing 了
@fractal314 自己写为什么会是 O(n)的?

应该是对象的创建占用了太多时间
asj
2016-01-28 07:43:36 +08:00
不是很确定理解清楚了你的问题
如果只是要找到两个字典中的序列号的话
各循环一次插入同一张 Hashtable ,以 series 为 key , value 为插入次数。之后遍历 Hashtable 取出 value 为 2 的条目。
fractal314
2016-01-28 07:50:31 +08:00
@billgreen1 1 楼和 4 楼的方法都是 o(n)的吧
ruoyu0088
2016-01-28 11:06:56 +08:00
先把所有序列的 nan 都删除掉,然后再进入双重循环。循环里面用 align(join="inner")对齐两个序列,相关文档: http://pandas.pydata.org/pandas-docs/version/0.17.1/generated/pandas.Series.align.html

这样不需要创建 DataFrame 对象,速度应该有所提升。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/253882

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX