如何在python中有效地扩展数组?

时间:2015-12-18 23:52:49

标签: python arrays numpy

我的问题是如何通过多次复制来有效地扩展数组。我试图通过复制每个样本N次来将我的调查样本扩展到全尺寸数据集。 N是签署样本的影响因子。 所以我写了两个循环来完成这个任务(下面粘贴的脚本)。它有效,但速度很慢。我的样本量是20,000,并尝试将其扩展到300万全尺寸..我可以尝试任何功能吗?谢谢您的帮助!

----我的剧本----

lines = np.asarray(person.read().split('\n'))
df_array = np.asarray(lines[0].split(' '))
for j in range(1,len(lines)-1):
    subarray = np.asarray(lines[j].split(' '))
    factor = int(round(float(subarray[-1]),0))
    for i in range(1,factor):
        df_array = np.vstack((df_array, subarray))
print len(df_array)

3 个答案:

答案 0 :(得分:2)

首先,您可以尝试使用numpy.loadtxt加载数据。

然后,要根据最后一列重复,请使用numpy.repeat

>>> data = np.array([[1, 2, 3],
...                  [4, 5, 6]])
>>> np.repeat(data, data[:,-1], axis=0)
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [4, 5, 6],
       [4, 5, 6],
       [4, 5, 6],
       [4, 5, 6],
       [4, 5, 6],
       [4, 5, 6]])

最后,如果您需要围绕data[:,-1],请将其替换为np.round(data[:,-1]).astype(int)

答案 1 :(得分:1)

反复堆叠numpy数组效率不高,因为它们并没有真正优化动态增长。每次vstack时,它都会为此时的数据大小分配一大块内存。

使用列表然后在最后构建你的数组,也许用这样的生成器:

def upsample(stream):
    for line in stream:
        rec = line.strip().split()
        factor = int(round(float(rec[-1]),0))
        for i in xrange(factor):
            yield rec

df_array = np.array(list(upsample(person)))

答案 2 :(得分:1)

您正在寻找的概念称为broadcasting。它允许您使用n dimensional数组的内容填充n-1 dimensional数组。

查看代码示例,您在循环中调用np.vstack()。广播将消除循环。

例如,如果您有一个n元素的一维数组,

>>> n = 5
>>> df_array = np.arange(n)
>>> df_array
array([0, 1, 2, 3, 4])

然后您可以创建一个新的n x 10数组:

>>> bigger_array = np.empty([10,n])
>>> bigger_array[:] = df_array
>>> bigger_array
array([[ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.]])

因此,只需一行代码,就可以用较小的数组填充它。

greater_array [:] = df_array

NB。避免使用python列表。它们比Numpy ndarray慢得多。