GVKun编程网logo

Pandas DataFrame 和 NumPy 数组的奇怪之处 - df.to_numpy()、np.asarray(df) 和 np.array(df) 给出了不同的内存使用情况

3

如果您想了解PandasDataFrame和NumPy数组的奇怪之处-df.to_numpy()、np.asarray(df)和np.array(df)给出了不同的内存使用情况的相关知识,那么本文是一

如果您想了解Pandas DataFrame 和 NumPy 数组的奇怪之处 - df.to_numpy()、np.asarray(df) 和 np.array(df) 给出了不同的内存使用情况的相关知识,那么本文是一篇不可错过的文章,我们将为您提供关于"ValueError: Failed to convert a NumPy array to an Tensor (Unsupported object type numpy.ndarray). 在 TensorFlow CNN 中进行图像分类、array – 为什么`Array(0,1,2)== Array(0,1,2)`不返回预期的结果?、Golang 中 `array` 和 `slice{array,array,...}` 有什么区别?、Numpy 1-dim array vs 2-dim array,其中一个维度的长度为 1的有价值的信息。

本文目录一览:

Pandas DataFrame 和 NumPy 数组的奇怪之处 - df.to_numpy()、np.asarray(df) 和 np.array(df) 给出了不同的内存使用情况

Pandas DataFrame 和 NumPy 数组的奇怪之处 - df.to_numpy()、np.asarray(df) 和 np.array(df) 给出了不同的内存使用情况

如何解决Pandas DataFrame 和 NumPy 数组的奇怪之处 - df.to_numpy()、np.asarray(df) 和 np.array(df) 给出了不同的内存使用情况

我正在将现有的 Pandas Dataframe 转换为 Numpy 数组。数据框没有 NaN 值并且不是稀疏填充的(从 .csv 文件读入)。另外,为了查看内存使用情况,我执行了以下操作:

sum(df.memory_usage)

  1. 2400128

sys.getsizeof(df)

  1. 2400144

以上16字节的小差异可以忽略不计,理解为使用sys.getsizeofdf.memory_usage求和时,大小计算不同,内存使用开销不同(供参考,{{ 1}} 或使用 df.info() 库。

现在,当将其转换为 Numpy 数组时,内存使用情况似乎存在巨大差异:

pandas_profiling

  1. sys.getsizeof(np.array(df))

2400120

  1. sys.getsizeof(df.to_numpy())

对我来说,这没有任何意义,因为两个数组的类型相同,大小和数据也相同:

120

  1. np.array(df)

array([[1.0000e+00,2.0000e+04,2.0000e+00,...,0.0000e+00,1.0000e+00],[2.0000e+00,1.2000e+05,2.0000e+03,[3.0000e+00,9.0000e+04,1.0000e+03,5.0000e+03,0.0000e+00],[1.1998e+04,1.0000e+00,3.0000e+03,4.0000e+03,[1.1999e+04,2.8000e+05,3.5000e+02,2.0950e+03,[1.2000e+04,1.0000e+00]])

  1. df.to_numpy() # or similarly,np.asarray(df)

我发现 array([[1.0000e+00,1.0000e+00]]) 使用 df.to_numpy() 来执行转换,所以我也尝试了这个:

np.asarray

  1. sys.getsizeof(np.asarray(df))

120 np.asarray(df) 的总使用量为 120 字节,而 df.to_numpy()2400120 字节!这没有任何意义!

两个数组都没有存储为稀疏数组,并且如上所示,具有相同的确切输出(通过检查类型,这是相同的)。

不知道如何解决这个问题,因为从内存的角度来看这似乎没有任何意义。我试图理解内存使用量的巨大差异,因为 np.array(df) 文件中的所有值都是整数或浮点数,并且不存在缺失值或 .csv 值。也许 NaN(因此 np.asarray(df))在做与 df.to_numpy() 不同的事情,或者 np.array(df) 在做一些奇怪的事情,但我似乎无法解决这个问题。

解决方法

numpy 具有 shapedtype 等属性,以及 data buffer,它是一个平面 C 数组,用于存储值。

  1. arr.nbytes # 2400000

告诉您该数据缓冲区的大小。因此,如果数组是 (300,10000) float dtype,则为 300*1000*8 字节。

getsizeof 2400120 正在报告该缓冲区加上用于数组对象本身、形状元组和 dtype 等的 120 个字节。

但是一个数组可能是另一个数组的 view。它将有自己的 120 个“开销”,但引用另一个数组的数据缓冲区。 getsizeof 只报告那个 120,而不是共享内存。实际上,它告诉我们该视图消耗了多少额外的内存。

数据框是一个复杂的对象,包含索引数组、列名列表(或数组)等。数据的存储方式取决于列数据类型。列可以被视为 Series 或类似 dtype 的列组。我认为在您的情况下,所有列都具有相同的 dtype,因此数据存储在 2d numpy 数组中。数据帧 getsizeof 报告的是该数组的数据缓冲区。

  1. df.values
  2. dt.to_numpy()

返回该数据数组的 view。因此 getsizeof 只报告 120。

np.array(df) 返回该数组的副本,它有自己的数据缓冲区,因此是完整大小。阅读它的docs

np.asarray(df) 有一个 copy=False 参数,因此在可能的情况下返回一个 view

总而言之,view 的概念是理解您所看到的差异的关键。 sys.getsizeof 对度量没有多大用处,除非您已经了解对象的组织方式。最好查看您使用的函数的文档,包括 np.arraynp.asarray.to_numpy

,

经过一番挖掘,我想我找到了这个问题的答案(虽然我认为它并不令人满意)。

首先,我分别存储了每个值,以确保将这些值分配给变量:

  1. nparr1 = np.array(df)
  2. nparr2 = df.to_numpy()

接下来比较了每一项的类型和大小,可以看出这些数组中的每一个在格式或存储上都没有区别。这很莫名其妙,然后发现了numpy数组itemsizesize的以下内容。接下来,对每个项目执行 .itemsize.size

nparr1.itemsize * nparr1.size

  1. 2400000

nparr2.itemsize * nparr2.size

  1. 2400000

好奇怪!现在这些值正在匹配。这也可以使用与 nbytes 一起使用的字节进行检查,产生与上述相同的值。

nparr1.nbytes

  1. 2400000

nparr2.nbytes

  1. 2400000

所以并不是说有什么神奇的压缩算法,而是内存使用量就在那里。似乎 sys.getsizeof 由于某种原因有奇怪的行为(仍未解决)。但是,请注意与上述问题的不同之处在于:

sys.getsizeof(np.array(df))

  1. 2400120

sys.getsizeof(df.to_numpy())

  1. 120

现在,奇怪的是,nparr1.nbytes 产生了 2400000。看起来 2400120 - 2400000 = 120。因此,似乎 sys.getsizeof(df.to_numpy()) 产生了开销成本(也许是指向该内存地址的指针),而 sys.getsizeof(np.array(df)) 产生了 2400000 的完整内存负载加上 120 的开销,即 2400120。我希望这是正确的分析,如果其他人有其他见解或 df.to_numpy()/np.asarray(df)np.array(df) 的幕后实际发生了什么以及数据如何存储在内存中,以及 sys.getsizeof 的奇怪行为,我很乐意了解更多内存操作的不同之处。

我已经与一位同事核对过,这就是我们的决定(我的同事也在同一个 .csv 文件上独立测试了这个并得出了相同的结论)。然而,对于完全相同的 numpy 数组的幕后真正发生的事情以及这种意想不到的奇怪行为,这并不是一个令人满意的答案。

"ValueError: Failed to convert a NumPy array to an Tensor (Unsupported object type numpy.ndarray). 在 TensorFlow CNN 中进行图像分类

如何解决"ValueError: Failed to convert a NumPy array to an Tensor (Unsupported object type numpy.ndarray). 在 TensorFlow CNN 中进行图像分类

我一直在研究用于图像分类的 CNN,但我一直遇到同样的错误,我的数据正在加载到数据帧中,但我无法将其转换为张量以将其输入 CNN。如您所见,我使用此代码将图片加载到数据框中:

  1. for i in range(len(merged)):
  2. full_path = merged.iloc[i][''Image Path Rel'']
  3. filename = full_path[-22:-1] + ''G''
  4. try:
  5. img = img_to_array(load_img(''D:/Serengeti_Data/Compressed/Compressed/'' + filename,target_size=(32,32,3)))
  6. except:
  7. img = np.zeros((32,3),dtype=np.float32)
  8. images = images.append({''Capture Id'' : merged.iloc[i][''Capture Id''],''Image'' : img},ignore_index = True)
  9. else:
  10. images = images.append({''Capture Id'' : merged.iloc[i][''Capture Id''],ignore_index = True)

然后,一旦我使用 load_img()img_to_array() 加载了图像,我进行了重塑以获得所需的 (32,3) 形状。还通过将 Image 列除以 255 来标准化这些值。

然后我这样做是为了尝试将其转换为张量:

  1. train_tf = tf.data.Dataset.from_tensor_slices(images[''Image''])
  2. # Also tried this,but didn''t got the same results:
  3. # train_tf = tf.convert_to_tensor(train_df[''Image''])

但不断收到错误:

ValueError: 无法将 NumPy 数组转换为张量(不支持的对象类型 numpy.ndarray)

我也尝试跳过它并立即尝试适应我们的模型,但得到了完全相同的错误:

  1. trying_df = pd.DataFrame(images[''Image''])
  2. target_df = pd.DataFrame(targets)
  3. animal_model = models.Sequential()
  4. animal_model.add(layers.Conv2D(30,kernel_size = (3,padding = ''valid'',activation = ''relu'',input_shape =(32,3)))
  5. animal_model.add(layers.MaxPooling2D(pool_size=(1,1)))
  6. animal_model.add(layers.Conv2D(60,kernel_size=(1,1),activation = ''relu''))
  7. animal_model.add(layers.Flatten())
  8. animal_model.add(layers.Dense(100,activation = ''relu''))
  9. animal_model.add(layers.Dense(10,activation = ''softmax''))
  10. ## compiler to model
  11. animal_model.compile(loss = ''categorical_crossentropy'',metrics = [''accuracy''],optimizer =''adam'')
  12. ## training the model
  13. animal_model.fit(trying_df,target_df,batch_size = 128,epochs = 15)
  14. animal_model.summary()

TensorFlow 版本:2.4.1

Numpy 版本:1.19.5

熊猫版本:1.0.1

解决方法

为了加载图像,您可以使用以下代码:

  1. image = cv2.imread(filename)
  2. image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)

为了调整图像的大小和缩放比例,最好让模型“嵌入”预处理功能。

  1. IMG_SIZE = 180
  2. resize_and_rescale = tf.keras.Sequential([
  3. layers.experimental.preprocessing.Resizing(IMG_SIZE,IMG_SIZE),layers.experimental.preprocessing.Rescaling(1./255)
  4. ])
  5. model = tf.keras.Sequential(
  6. [
  7. resize_and_rescale,layers.Conv2D(32,3,activation="relu"),layers.MaxPooling2D(),layers.Conv2D(64,layers.Conv2D(128,layers.Flatten(),layers.Dense(128,layers.Dense(len(class_names),activation="softmax"),]
  8. )
  9. model.compile(
  10. optimizer="adam",loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=["accuracy"],)

注意:
处理图像时使用 tf.Data 而不是 numpy 数组。您可以使用以下代码作为示例:
https://github.com/alessiosavi/tensorflow-face-recognition/blob/90d4acbea8f79539826b50c82a63a7c151441a1a/dense_embedding.py#L155

array – 为什么`Array(0,1,2)== Array(0,1,2)`不返回预期的结果?

array – 为什么`Array(0,1,2)== Array(0,1,2)`不返回预期的结果?

据我所知,Scala的==定义了两个对象的自然相等。

我期望Array(0,1,2)== Array(0,2)比较自然等式。例如,检查与其他数组的相应元素相比,数组的所有元素是否都返回true。

人们告诉我,Scala的数组只是一个Java [],只比较身份。是不是更有意义的重写Array’sequals方法比较自然平等?

解决方法

Scala 2.7试图向Java []数组添加功能,并且遇到了有问题的角落。 Scala 2.8声明Array [T]是T [],但它提供包装器和等效。

尝试下面2.8(编辑/注:从RC3,GenericArray是ArraySeq – 感谢retronym指出这一点):

import scala.collection.mutable.{GenericArray=>GArray,WrappedArray=>WArray}
scala> GArray(0,2) == GArray(0,2)
res0: Boolean = true

scala> (Array(0,2):WArray[Int]) == (Array(0,2):WArray[Int])
res1: Boolean = true

GenericArray的行为就像Array,除了所有的Scala集合好处添加进来。WrappedArray wraps Java [] array;上面,我把一个简单的数组给它(比调用隐式转换函数容易),然后比较包装的数组。这些包装,尽管支持一个[]数组,也给你所有的收集好东西。

Golang 中 `array` 和 `slice{array,array,...}` 有什么区别?

Golang 中 `array` 和 `slice{array,array,...}` 有什么区别?

golang 中 `array` 和 `slice{array,array,...}` 有什么区别?

Golang 中 `array` 和 `slice{array,array,...}` 有什么区别?这是很多初学者常问的问题。php小编子墨为您解答:在Golang中,`array` 是一个固定长度的序列,一旦定义后,长度就无法改变。而 `slice` 则是一个动态长度的序列,可以根据需要进行扩容或缩小。此外,`array` 的长度是在定义时确定的,而 `slice` 的长度可以在运行时动态改变。因此,在使用时,需要根据实际需求选择合适的数据结构。

问题内容

我很想知道为什么,请给我一点提示。

我想将一个数组附加到res中,res是一个二维切片。所以我需要先转换。 当我将数组转换为切片时,出现错误。

// i need a map to remove duplicates
mm := map[[3]int]bool{}
mm[[3]int{-1, -1, 2}] = true
mm[[3]int{-1, -1, 2}] = true
mm[[3]int{-1, 0, 1}] = true

var res [][]int
for k, _ := range mm {
    res = append(res, k[:])
}
fmt.printf("the res is %v\n", res)
登录后复制
the res is [[-1 0 1] [-1 0 1]]
登录后复制

但是结果不是我想要的。

然后我试探性地修改了一下for循环

立即学习“go语言免费学习笔记(深入)”;

for k, _ := range mm {
    //res = append(res, k[:])
    res = append(res, []int{k[0], k[1], k[2]})
}
登录后复制
the res is [[-1 0 1] [-1 -1 2]]
登录后复制

现在结果是对的,但是为什么呢? k[:] 和 []int{k[0],k[1],k[2]} 有什么区别?

解决方法

将循环更改为

for k, _ := range mm {
    j := k
    res = append(res, j[:])
}
登录后复制

您的原始循环声明了一个类型为 [3]int 的变量 k,该变量在内存中具有特定位置。循环的每次迭代,都会将映射 mm 中的不同键复制到该变量。到目前为止,一切顺利。

当您使用 k[:] 将其转换为切片时,它会创建一个切片标头,指向数组 k。这里出错了 - 循环的下一次迭代,k 的值被覆盖。循环中创建的所有切片都指向内存中同一位置的同一支持数组 k。

通过首先将 k 的值复制到在循环内声明的变量,您可以为每个切片提供自己的支持数组,从而避免了该问题。

以上就是Golang 中 `array` 和 `slice{array,array,...}` 有什么区别?的详细内容,更多请关注php中文网其它相关文章!

Numpy 1-dim array vs 2-dim array,其中一个维度的长度为 1

Numpy 1-dim array vs 2-dim array,其中一个维度的长度为 1

如何解决Numpy 1-dim array vs 2-dim array,其中一个维度的长度为 1

在 Matlab 中没有一维数组的概念。所有数组都至少有两个维度。所有“向量”都是“行向量”(1xn 数组)或“列向量”(nx1 数组)。

另一方面,在 NumPy 中,数组也可以是一维的。于是就有了“纯向量”(维度n)、“行向量”(维度1xn)和“列向量”(维度nx1)的概念。

现在我从 Matlab 转向 Python,这让我很头疼。

举个例子,考虑这样一种情况,我必须移动一个 nxk(n 通常很大,但 k 可以是 1)矩阵的行,称之为 A,向下一行,然后添加一行零第一行。

在 Matlab 中我会做

[n,k] = size(A);
B      = [zeros(1,k); A(1:end-1,:)];

在 Numpy 中,我希望这不仅适用于二维输入,而且适用于一维输入。 所以一个有效的解决方案是

import numpy as np

if A.ndim == 1:
    B = np.concatenate((np.zeros(1),A[:-1]),axis=0)

if A.ndim == 2:
    (n,k) = A.shape
    B = np.concatenate((np.zeros((1,k)),A[:-1,:]),axis=0)

但这太沉重了。有没有更好(更巧合)的方法?

更一般地说,我总是有这个问题:如果我写了一个接受二维数组 (nxk) 的函数,称它为 arr其中 k 很可能是 1 ,该函数可能在一维数组上失败(例如,如果我执行 arr[0,:])。 但我希望它也适用于一维数组,因为它们在道德上与其中一个维度为 1 的二维数组相同。

当然一种方法是放一些类似的东西

if arr.ndim == 1
    arr = arr.reshape((arr.shape[0],1))

在函数的最开始,这样就保证函数有一个二维数组可以使用。

但这并不完全令人满意。例如,我的函数可能会返回一个与输入 (nxk) 形状相同的数组。但是如果输入是一维的,我希望它也返回一维的东西,而不是 (nx1)。所以为了处理这种情况,我需要添加其他冗长的 if 语句和重塑,这会使我的代码看起来更重和更丑。

最好的出路是什么?

解决方法

当涉及到数组大小时,我认为 numpy 的“严格性”(与 MATLAB 相比)是一种优势,我觉得它使许多事情变得更加可预测。

我针对您的第一个问题提出以下解决方案,其中可能包含一些用于解决未来问题的有用工具。第一个工具是 "ellipsis" (...) 对象,可用于索引。当您在索引中看到这三个点时,您可以将其视为根据需要替换尽可能多的 :。例如,如果 A.shape = (42,2021,69,7)A[...,1,:]A[:,:,:] 相同。在这里我应该补充一点,很明显,每个索引表达式只能使用其中之一。为了编写处理任意维数数组的函数,这是一件非常有用的事情。

第二个(这个答案不是必需的)是你可以将它用于 np.onesnp.zeros 等,你总是有相应的函数 np.ones_like 或 {{1 }},让您避免许多繁琐的计算。

所以在下面我们使用这些首先创建一个具有正确形状的新数组,而无需进行任何算术运算。我们只是在我们想要替换的东西上调用 np.zeros_like(在本例中是 np.zeros_like 的最后一个“超行”,但它可以是其中的任何一个)。同时,省略号运算符可以方便地处理我们可能存在的任意数量的维度:

A

Try it online!

我们今天的关于Pandas DataFrame 和 NumPy 数组的奇怪之处 - df.to_numpy()、np.asarray(df) 和 np.array(df) 给出了不同的内存使用情况的分享就到这里,谢谢您的阅读,如果想了解更多关于"ValueError: Failed to convert a NumPy array to an Tensor (Unsupported object type numpy.ndarray). 在 TensorFlow CNN 中进行图像分类、array – 为什么`Array(0,1,2)== Array(0,1,2)`不返回预期的结果?、Golang 中 `array` 和 `slice{array,array,...}` 有什么区别?、Numpy 1-dim array vs 2-dim array,其中一个维度的长度为 1的相关信息,可以在本站进行搜索。

本文标签: