【发布时间】:2013-03-09 03:52:52
【问题描述】:
我试图了解为什么在函数中和独立使用 numpy.loadtxt 时会得到非常不同的分析/计时数字。
设置要读取/配置的数据
- 1个26列1000行的文件,文件中的每一项都是随机浮点数
- 文件以空格分隔
- 文件中的第一行是一个空格分隔的标题,有 26 个列名
- 有关如何生成此数据的代码,请参见下文
单独分析 numpy.loadtxt
假设我有一个具有上述属性的名为“test.out”的文件:
>>> f = open('test.out', 'r');f.readline()
'a b c d e f g h i j k l m n o p q r s t u v w x y z\n'
>>> %timeit -n 1 np.loadtxt(f, unpack=True)
1 loops, best of 3: 30 us per loop
在函数内部分析 numpy.loadtxt
现在我想在函数内部分析numpy.loadtxt(使用line_profiler)和ipython中的%lrpun魔法:
>>> %lprun -f file_to_numpy_ordered_dict file_to_numpy_ordered_dict('test.out')
Timer unit: 1e-06 s
Function: file_to_numpy_ordered_dict at line 88
Total time: 0.085642 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
88 def file_to_numpy_ordered_dict(filename):
89 """
90 Read a space-separated-value file as a dict of columns, keyed by
91 column header where each column (dict value) is a numpy array.
92 """
93
94 1 430 430.0 0.5 with open(filename, 'r') as file_obj:
95 1 363 363.0 0.4 headers = file_obj.readline().split()
96
97 # unpack=True b/c want data organized as column based arrays, not rows
98 1 84634 84634.0 98.8 arrs = np.loadtxt(file_obj, unpack=True)
99
100 1 66 66.0 0.1 ret_dict = collections.OrderedDict()
101 27 34 1.3 0.0 for ii, colname in enumerate(headers):
102 26 114 4.4 0.1 ret_dict[colname] = arrs[ii]
103
104 1 1 1.0 0.0 return ret_dict
为什么?
为什么单独调用 numpy.loadtxt 只需要 30us 而在这个函数中调用它大约需要 0.085 秒?我觉得我在这里遗漏了一些明显的东西,但看起来函数在每个场景中被调用的参数完全相同,等等。
因为我使用的是%timeit 和%lprun,这是不是有些奇怪的区别?也许由于某种原因无法比较这些数据?
随机数据创建详情
-
文件数据是使用以下代码生成的: def generate_test_data(column_names, row_count, 文件名): """ 生成大小为(row_count, len(column_names))的随机测试数据文件
column_names - List of column name strings to use as header row row_count - Number of rows of data to generate filename - Name of file to write test data to """ col_count = len(column_names) rand_arr = np.random.rand(row_count, col_count) header_line = ' '.join(column_names) np.savetxt(filename, rand_arr, delimiter=' ', fmt='%1.5f', header=header_line, comments='')
【问题讨论】:
-
实际上,我认为这是我传递给
%timeit的参数的问题。我错误地假设-n 1只会调用该函数一次,但-n用于在循环中执行 n 次。所以,我需要额外的参数-r 1来重复 loop 一次。否则,%timeit将返回 3 个调用中最好的一个,这意味着 3 个调用中的 2 个不必读取任何数据,因为文件是在第一次调用时读取的。因此,最快的迭代显然是numpy.loadtxt没有读取数据的迭代。 -
%timeit的 真实 时间应该是:每循环 32.4 毫秒,这更有意义。 -
所以,正如我所料,我似乎回答了这个问题,但遗漏了一些明显的东西。我应该关闭它还是发布 cmets 作为答案?这种事情的标准是什么?
-
只需添加您的解决方案作为答案(甚至还有一个徽章!)。