Python 将二维数组的字符串表示形式从CSV列读入二维numpy数组
我有一个pandas dataframe,其中一列包含与灰度图像中的像素数据相对应的2D numpy数组。这些2D numpy阵列的形状为Python 将二维数组的字符串表示形式从CSV列读入二维numpy数组,python,arrays,pandas,numpy,csv,Python,Arrays,Pandas,Numpy,Csv,我有一个pandas dataframe,其中一列包含与灰度图像中的像素数据相对应的2D numpy数组。这些2D numpy阵列的形状为(480640)或(490640)。dataframe具有包含其他信息的其他列。然后,我通过pandas的to_csv()函数从中生成一个csv文件。现在我的问题是:我的2D numpy数组在我的CSV中都显示为字符串,那么我如何才能读回它们并再次将它们转换为2D numpy数组? 我知道在StackOverflow上也有类似的问题,但我找不到任何真正关注2D
(480640)
或(490640)
。dataframe具有包含其他信息的其他列。然后,我通过pandas的to_csv()
函数从中生成一个csv文件。现在我的问题是:我的2D numpy数组在我的CSV中都显示为字符串,那么我如何才能读回它们并再次将它们转换为2D numpy数组?
我知道在StackOverflow上也有类似的问题,但我找不到任何真正关注2D numpy阵列的问题。它们似乎主要是1D numpy阵列,而提供的解决方案似乎不起作用
非常感谢您的帮助
更新:
根据要求,我在下面添加了一些代码,以澄清我的问题所在
# Function to switch images to grayscale format
grayscale(img):
cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Iterating through my dataframe (called data), reading all image files, making them grayscale and then adding them to my collection.
grayscale_images = []
for index, row in data.iterrows():
img_path = row['Image path']
cv_image = cv2.imread(img_path)
gray = grayscale(cv_image)
grayscale_images.append(gray)
# Make numpy array elements show without truncation
np.set_printoptions(threshold=sys.maxsize)
# Adding a new column to the dataframe containing each image's numpy array corresponding to pixels
data['Image data'] = grayscale_images
因此,当我在其他列上完成该操作和其他操作时,我将数据帧导出为CSV,如下所示:
data.to_csv('new_dataset.csv', index=False)
在另一个Jupyter笔记本中,我尝试读取我的CSV文件,然后提取图像的numpy数组,将它们作为输入输入输入到卷积神经网络,作为监督训练的一部分
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import sys
import re
data = pd.read_csv('new_dataset.csv')
# data.head() -- It looks fine here
# Config to make numpy arrays display in their entirety without truncation
np.set_printoptions(threshold=sys.maxsize)
# Checking if I can extract a 2D numpy array for conversion from a cell.
# That's where I notice it's a string, and I'm having trouble turning it back to a 2D numpy array
image_arr = data.iloc[0,0]
但是,我一直无法将我的字符串类型表示从CSV文件转换回2D numpy数组,尤其是在将数据帧导出到CSV之前,它的形状是(490640)
。data=pd.read\u CSV('new\u dataset.CSV')
方法1:data.values
方法2:data.to_numpy()
如果data.shape是2D DataFrame,则上述两种方法将给出2D numpy数组。
试试看
下面是一个演示:
df = pd.DataFrame(data={"A": [np.random.randn(480, 640), np.random.randn(490, 640)], "B": np.arange(5, 7)})
print(type(df.to_numpy()[0, 0])) # <class 'numpy.ndarray'>
print(df.to_numpy()[0, 0].shape) # (480, 640)
print(type(df.to_numpy()[1, 0])) # <class 'numpy.ndarray'>
print(df.to_numpy()[1, 0].shape) # (490, 640)
df=pd.DataFrame(data={“A”:[np.random.randn(480640),np.random.randn(490640)],“B”:np.arange(5,7)})
打印(键入(df.to_numpy()[0,0]))#
打印(df.to_numpy()[0,0].shape)#(480,640)
打印(键入(df.to_numpy()[1,0])#
打印(df.to_numpy()[1,0].shape)#(490640)
过一会儿我就要开始工作了,您可以先试试,如果有任何问题,请再次询问。使用数组字符串构造csv:
In [385]: arr = np.empty(1, object)
In [386]: arr[0]=np.arange(12).reshape(3,4)
In [387]: S = pd.Series(arr,name='x')
In [388]: S
Out[388]:
0 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
Name: x, dtype: object
In [389]: S.to_csv('series.csv')
/usr/local/bin/ipython3:1: FutureWarning: The signature of `Series.to_csv` was aligned to that of `DataFrame.to_csv`, and argument 'header' will change its default value from False to True: please pass an explicit value to suppress this warning.
#!/usr/bin/python3
In [390]: cat series.csv
0,"[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]"
加载它:
In [391]: df = pd.read_csv('series.csv',header=None)
In [392]: df
Out[392]:
0 1
0 0 [[ 0 1 2 3]\n [ 4 5 6 7]\n [ 8 9 10 11]]
In [394]: astr=df[1][0]
In [395]: astr
Out[395]: '[[ 0 1 2 3]\n [ 4 5 6 7]\n [ 8 9 10 11]]'
分析数组的字符串表示形式:
In [396]: astr.split('\n')
Out[396]: ['[[ 0 1 2 3]', ' [ 4 5 6 7]', ' [ 8 9 10 11]]']
In [398]: astr.replace('[','').replace(']','').split('\n')
Out[398]: [' 0 1 2 3', ' 4 5 6 7', ' 8 9 10 11']
In [399]: [i.split() for i in _]
Out[399]: [['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10', '11']]
In [400]: np.array(_, int)
Out[400]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
不能保证这是最漂亮、最干净的解析,但它给出了您必须完成的工作的想法。我正在重新发明轮子,但寻找复制品花费了太长时间
如果可能,尽量避免将此类数据帧保存为csv。csv格式适用于干净的2d表格,简单一致的列由分隔符分隔
在大多数情况下,避免这样的数据帧/系列。序列可以具有对象数据类型。每个对象元素都可能很复杂,例如列表、字典或数组。但是我不认为熊猫有特殊的功能来处理这些情况
numpy
也有对象数据类型(如myarr
),但列表通常也一样好,甚至更好。构建这样一个数组可能很棘手。这样一个数组上的数学是命中或未命中的。对象数组上的迭代比列表上的迭代慢
===
re
也可能起作用。例如,将空格替换为逗号:
In [408]: re.sub('\s+',',',astr)
Out[408]: '[[,0,1,2,3],[,4,5,6,7],[,8,9,10,11]]'
还是不太对。有一些前导逗号将阻塞
eval向数据
数据帧添加两列:使用np.tostring()
和原始形状将灰度图像转换为字节
grayscale_images = []
grayscale_shapes = []
for index, row in data.iterrows():
img_path = row['Image path']
cv_image = cv2.imread(img_path)
gray = grayscale(cv_image)
grayscale_images.append(gray.tostring())
grayscale_shapes.append(gray.shape)
读取CSV,然后使用“np.fromstring()”恢复2d np数组,并重置正确的形状
imagedata = np.fromstring(df.loc(...)) # index the image cell
imagedata.shape = df.loc(...) # index the corresponding shape
将数据帧存储为CSV文件的原因是什么?它会被另一个需要CSV输入的程序读取吗?如果没有,我建议使用pickle。@DYZ我将在TensorFlow模型中读取CSV(作为数据集),因为我正在使用Keras创建卷积神经网络来对图像进行分类。您仍然建议使用pickle吗?如果您的CSV文件只是临时存储,那么我建议您使用pickle。@DYZ实际上我也希望与其他同事共享它,而且它不是真正的临时存储。我想这就是我尚未决定的地方。你也可以和你的同事分享你的pickle文件。只要您不打算将CSV文件输入到能够将numpy数组识别为字符串的第三方软件中,使用CSV就没有意义。@Isaac Asante,碰巧我熟悉您正在做的工作,data.values或data.to_numpy()我不知道这对OP有什么帮助。他只是希望将从以前存储的CSV读取的数据帧转换成numpy,这通常是在与机器学习相关的学术工作中完成的。不,这不是他想要做的。你看过帖子了吗?@AyiF嗯。。。谢谢,但很抱歉,这并不能解决我的问题。我确实返回了numpy数组,但它们是字符串数组,形状是错误的。它们还包含\n
字符,等等。您的详细回答主要包含我的问题的解决方案。我只是做了一些调整,但是非常感谢!在对代码进行更改后,我能够将所有内容组合到一个函数中,并使用Pandas中的apply()
函数在数据框的“Image data”列上运行它。现在一切都好了;所有图像数据字符串现在都转换为2D numpy数组。