在for循环中追加数组

时间:2019-04-07 17:06:26

标签: python pandas numpy

我有一个包含1000行和1000列的数据框。我试图使用for循环从该数据帧生成一个numpy数组,我使用for循环每个周期随机选择5列。我需要附加或连接每个周期生成的每个数组(1000行和5列)。但是,可以看到如果不先指定尺寸就无法创建numpy数组。

我尝试了以下代码:

import numpy as np
import pandas as pd


df = pd.DataFrame(np.random.choice([0.0, 0.05], size=(1000,1000)))

l =  np.array([])

for i in range(0,100):
 rand_cols = np.random.permutation(df.columns)[0:5]
 df2 = df[rand_cols].copy()
 l = np.append(l, df2, axis=0)

但是,出现以下错误:

ValueError: all the input arrays must have same number of 
dimensions

此代码总结了我在做什么,但是,根据此示例,我需要的结果是由1000行和500列组成的数组,该数组是通过将每个for循环生成的每个数组的连接生成的循环。

3 个答案:

答案 0 :(得分:4)

列表附加总是比np.append更好。它更快,更容易正确使用。

但是让我们更详细地看一下您的代码:

In [128]: df = pd.DataFrame(np.random.choice([0.0, 0.05], size=(1000,1000)))    
In [129]: l = np.array([])                                                      
In [130]: rand_cols = np.random.permutation(df.columns)[0:5]                    
In [131]: rand_cols                                                             
Out[131]: array([190, 106, 618, 557, 514])
In [132]: df2 = df[rand_cols].copy()                                            
In [133]: df2.shape                                                             
Out[133]: (1000, 5)
In [134]: l1 = np.append(l, df2, axis=0)                                        
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-134-64d82acc3963> in <module>
----> 1 l1 = np.append(l, df2, axis=0)

/usr/local/lib/python3.6/dist-packages/numpy/lib/function_base.py in append(arr, values, axis)
   4692         values = ravel(values)
   4693         axis = arr.ndim-1
-> 4694     return concatenate((arr, values), axis=axis)
   4695 
   4696 

ValueError: all the input arrays must have same number of dimensions

自指定轴以来,所有np.append所做的就是:

np.concatenate([l, df2], axis=0)

l的形状为(0,),df2的形状为(1000,5)。 1d和2d,因此抱怨尺寸。

从2d l数组开始工作:

In [144]: l = np.zeros((0,5))                                                   
In [145]: np.concatenate([l, df2], axis=0).shape                                
Out[145]: (1000, 5)
In [146]: np.concatenate([df2, df2], axis=0).shape                              
Out[146]: (2000, 5)

我认为np.append应该被弃用。我们看到太多SO错误。如您的情况所示,很难创建正确的初始数组。 np.array([])仅在构建一维数组时有效。再加上重复的连接速度很慢,每次都会创建一个全新的数组。

答案 1 :(得分:1)

IIUC

function myFunction(myString) {

  if (myString.includes("-")) {
      return "00:00";
  }else{
      return myString;
  }

答案 2 :(得分:0)

建议的解决方案

出现此错误的原因是,您试图将形状为(1000,5)的矩阵(0, 4) # 1 + 2 + 3 + 4 + 5 = 15 (1, 3) # 2 + 3 + 7 = 12 附加到形状为df2的矩阵(0,)(仅一维)。问题是,使用numpy时,两个串联的矩阵必须匹配维,并且除要附加的维之外的所有维都必须对齐,即,您应该已将l初始化为形状为(0,5)< / em>。

这是该代码的有效版本:

l

建议的改进

现在,最佳实践是避免在循环内添加矩阵,因为这在计算上效率不高(每次迭代都必须创建一个新的numpy数组,这需要花费时间)。您最好将循环迭代的结果附加到标准python列表中,并等待直到循环执行结束,以将所有结果堆叠在一起。

代码如下:

import numpy as np
import pandas as pd


df = pd.DataFrame(np.random.choice([0.0, 0.05], size=(1000,1000)))

l =  np.empty(shape=(0, 5))

for _ in range(0,100):
    rand_cols = np.random.permutation(df.columns)[0:5]
    df2 = df[rand_cols]
    l = np.append(l, df2, axis=0)

在这里,我使用numpy.vstack沿行轴进行连接。其他具有适当参数的numpy函数将为您提供相同的结果。请注意,无需将熊猫数据帧转换为numpy数组。

在我的计算机上,这一小小的改进将计算时间从164毫秒减少到107毫秒(从快速执行每个版本中选取的值)。当然,这在这里并不重要,但是我认为这很高兴:)