我有一堆CSV文件包含文本格式的数组数据。我需要用它们制作一个大的loadtxt()
数组。我不想摄取CSV,但这不在我的掌控之中。
我这样做的方法是使用numpy
从每个CSV文件构造一个numpy
数组,然后通过连接这些较小的数组来构造更大的数组。事实证明这是瓶颈。
理想情况下,我想要一个采用数组切片并将CSV数据加载到位的API。有scipy
,nickNameTF.text = @"eweسبيب";
NSLog(@"nickNameTF.textnickNameTF.text===%@", nickNameTF.text);
NSString *emailRegex = @"\p{Arabic}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
if ([emailTest evaluateWithObject:nickNameTF.text]) {
DTAlertView *myAl = [DTAlertView alertViewWithTitle:localize(@"myErr") message:localize(@"srNicc") delegate:nil cancelButtonTitle:localize(@"dismiss") positiveButtonTitle:nil];
[myAl setDismissAnimationWhenButtonClicked:DTAlertViewAnimationSlideTop];
[myAl showWithAnimation:DTAlertViewAnimationSlideBottom];
nickNameTF.enabled = YES;
nickNameTF.userInteractionEnabled = YES;
}
或其他模块/包来做这件事,还是我必须自己动手。
答案 0 :(得分:1)
loadtxt
的第一个参数必须是一个可迭代的文本行。一次打开所有文件并将它们与itertools.chain
链接在一起,或者更好的是,定义一个生成器函数依次打开每个文件并生成所有行:
filenames = ["foo.csv", "bar.csv"]
def all_files():
for fn in filenames:
with open(fn) as f:
for line in f:
yield line
my_array = numpy.loadtxt(all_files(), delimiter=",")
答案 1 :(得分:1)
np.loadtxt
逐行读取您的文件(或其他来源)。它拆分行并转换字符串,并将所有内容收集为元组列表。它只是在最后将它传递给np.array
(带有dtype)。
我怀疑您是在列表中收集这些数组,然后将其传递给np.concatenate
。连接动作应该非常快。我希望多个loadtxt
调用更慢。
我不知道codewarriors
是否接近,将多个文件传递给一个loadtxt
会更快或更快。它仍在逐行读取数据,并将其收集到列表中 - 所有文件的一个大列表。然后是最终的np.array
构造。如果每个文件中都有标题/尾部行,则all_files
生成器必须处理这些行。
如果你知道每个csv文件的大小,你可以构造一个大的空数组,并将每个loadtxt
结果插入其中。
e.g。
N = `number of files`
# each with M rows, L columns
BigMat = np.empty((N,M,L))
for i in range(N):
arr = np.loadtxt(filenames[i], ...)
BigMat[i,:,:] = arr
其他SO问题表明,concatente
和for i...; M[i...]=
方法的速度大致相同。
另一种方法是逐行填写BigMat
。我相信Python
csv
读者会逐行为您提供文件,并将其拆分为字段。你必须自己转换为float / int等。这听起来不会更快。
BigMat[i,j...] = [float(i) for i in fcsv.reader(lines)]
最后一个选择是使用pandas
更快的csv加载程序。
时间测试;从(m,n)
整数列表生成n
数组的不同方法。该列表模拟从文件中解析一行的结果。
def foo1(x,m):
# fill in an array with list
M = np.empty((m,len(x)),int)
for i in range(m):
M[i,:] = x
return M
def foo2(x,m):
# fill in array - convert list to array first
M = np.empty((m,len(x)),int)
for i in range(m):
M[i,:] = np.array(x)
return M
def foo3(x,m):
# append lists; create array
L = []
for i in range(m):
L.append(x)
M = np.array(L)
return M
def foo4(x,m):
# append arrays; vstack
L = []
for i in range(m):
L.append(np.array(x))
M = np.vstack(L)
return M
def foo5(x,m):
# append 2d array; concatente
L = []
for i in range(m):
L.append(np.array([x]))
M = np.concatenate(L,axis=0)
return M
In [308]: timeit foo1(range(100),1000)
10 loops, best of 3: 24.8 ms per loop
In [309]: timeit foo2(range(100),1000)
10 loops, best of 3: 27.8 ms per loop
In [310]: timeit foo3(range(100),1000)
100 loops, best of 3: 18.6 ms per loop
In [311]: timeit foo4(range(100),1000)
10 loops, best of 3: 29.6 ms per loop
In [312]: timeit foo5(range(100),1000)
10 loops, best of 3: 24 ms per loop
附加列表,只构建一次数组比其他时间具有适度的时间优势。这最接近codewarriors
解决方案。我可以通过处理行组来优化测试,以更好地模拟使用多个文件。
从磁盘复制到内存,然后从字符串列表转换为数字列表是不可避免的。这些数字必须至少再复制一次才能将它们放入连续的内存块中。避免一个或两个中间副本似乎没有太大的区别。
我尝试了创建(m,n,l)
数组的变体,即。 m个文件,有n行,l列。 foo2
样式 - 在M中插入(n,l)大小的数组略微更好。这忽略了loadtxt
花费开放和阅读文件的时间。