将csv加载到numpy数组的特定切片中

时间:2015-07-16 10:32:34

标签: csv numpy

我有一堆CSV文件包含文本格式的数组数据。我需要用它们制作一个大的loadtxt()数组。我不想摄取CSV,但这不在我的掌控之中。

我这样做的方法是使用numpy从每个CSV文件构造一个numpy数组,然后通过连接这些较小的数组来构造更大的数组。事实证明这是瓶颈。

理想情况下,我想要一个采用数组切片并将CSV数据加载到位的API。有scipynickNameTF.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; } 或其他模块/包来做这件事,还是我必须自己动手。

2 个答案:

答案 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问题表明,concatentefor 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花费开放和阅读文件的时间。