vectorize 不能替代迭代。这是为您提供numpy 广播的全部功能的一种方式。生成的函数接受一个或多个数组,将它们一起广播,然后将一个简单的值元组(即标量,每个数组中的一个)提供给包装函数。
在您的代码中,f 是行列表 - 文件中的所有行。
你可以这样做:
N = len(f)
for i in range(0,N,1000):
a = np.loadtxt(f[i:i+1000], delimiter=',')
<process array a>
换句话说,将f 的行以块的形式提供给loadtxt。
实际上,您不需要一次阅读所有行。您可以编写一个生成器,逐行读取文件并返回行块。
之前已经讨论过使用生成器来馈送loadtxt(或genfromtxt)。
矢量化的工作示例
In [121]: def processing(astr):
return list(map(int, astr.split(',')))[0] # py3
.....:
In [122]: processing(a[0])
Out[122]: 1
In [123]: fn=np.vectorize(processing, otypes=[int])
In [124]: fn(a)
Out[124]: array([1, 4, 7])
这个函数接受一个字符串并返回一个int。还不如
In [125]: [processing(l) for l in a]
Out[125]: [1, 4, 7]
我从参数中删除了delimiter 和dtype,因为我们不想遍历这些参数。 vectorize 有一个exclude 参数;但我不想玩那个。
vectorize 也为otypes 取多个值,但我还没有看到这种用法的示例。您的函数不起作用,因为它返回了一个序列(例如 3 个整数),但 vectorize 期望它返回一个值(一个标量浮点数或整数)。
如果您将 otypes 指定为对象,则您的 processing 确实有效 - 有点
In [126]: def processing(astr):
return list(map(int, astr.split(','))) # py3
.....:
In [127]: fn=np.vectorize(processing, otypes=[object])
In [128]: fn(a)
Out[128]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=object)
但为什么不只是迭代呢?
In [129]: [processing(l) for l in a]
Out[129]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [130]: np.array([processing(l) for l in a])
Out[130]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
我隐约记得一些关于使用vectorize 和object 返回时出现错误的问题。
当我在滚动时,我不妨说明一下广播:
这是你的函数,它接受 2 个值 - 一个字符串和一个函数,并将函数应用于拆分的每个元素:
In [131]: def processing(astr, conv):
return list(map(conv, astr.split(','))) # py3
.....:
In [132]: fn=np.vectorize(processing, otypes=[object])
现在vectorized 函数需要 2 个输入,例如列表和函数:
In [133]: fn(a,int)
Out[133]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=object)
或a(2 个列表)中每个字符串的不同函数
In [134]: fn(a,[int,float,str])
Out[134]: array([[1, 2, 3], [4.0, 5.0, 6.0], ['7', '8', '9']], dtype=object)
或者将第二个列表设为“列”列表 - 并返回一个 (2,3) 列表数组。一行是整数,另一行是浮点数。显然我可以用数组(0、1d、2d 等)替换列表。
In [136]: fn(a,[[int],[float]])
Out[136]:
array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]], dtype=object)
如果您需要这种输入灵活性,请使用vectorize。但是,如果您只是迭代一个数组或列表 - 直接执行。
我找到了多个otypes的例子:https://stackoverflow.com/a/30255971/901925
应用于本案:
In [140]: def processing(astr):
return tuple(map(int, astr.split(','))) # py3
.....:
重要的是它返回一个元组,而不是一个列表或数组。
In [141]: processing(a[0])
Out[141]: (1, 2, 3)
In [142]: fn=np.vectorize(processing, otypes=[int,int,int])
请注意,返回元组的每个项目都必须有一个 otype。
In [144]: fn(a)
Out[144]: (array([1, 4, 7]), array([2, 5, 8]), array([3, 6, 9]))
但[1, 4, 7] 是 3 个输入中每个输入的第一个值。它返回的是一组数组,而不是一个数组。
In [146]: x,y,z=fn(a)
In [147]: x
Out[147]: array([1, 4, 7])
这种行为困扰了另一个提问者,我怀疑这是否也是你想要的。 :)
https://stackoverflow.com/a/30088791/901925 - 带有时间测试的矢量化示例。