【问题标题】:numpy array saving to csvnumpy 数组保存到 csv
【发布时间】:2018-07-09 08:14:18
【问题描述】:

我正在尝试将 numpy 数组保存到 csv 文件,但出现了问题,

我使用了两种不同的解决方案,但它们都不起作用

我的 numpy 数组看起来像,

In[39]: arr[0]
Out[39]: 
array([ array([[ 30,  29, 198, ..., 149, 149, 149],
   [ 29,  29, 197, ..., 149, 149, 149],
   [ 29,  29, 197, ..., 149, 149, 149],
   ..., 
   [ 63,  63,  96, ..., 105, 104, 104],
   [ 63,  63,  96, ..., 106, 105, 105],
   [ 77,  77, 217, ..., 217, 217, 217]], dtype=uint8),
   list([0, 0, 0, 0, 0, 0, 0, 0, 0])], dtype=object)

它的形状是 (1200, 2) numpy 数组,我想把它保存到 csv 文件中,

带有 np.savetxt 功能

In[40]: np.savetxt("numpy_array.csv", arr, delimiter=',')
Traceback (most recent call last):
  File "D:\Program files\Anaconda3\lib\site-packages\numpy\lib\npyio.py", line 1254, in savetxt
    fh.write(asbytes(format % tuple(row) + newline))
TypeError: only length-1 arrays can be converted to Python scalars
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "D:\Program files\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2862, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-41-673bcc1d77a6>", line 1, in <module>
    np.savetxt("numpy_array.csv", arr, delimiter=',')
  File "D:\Program files\Anaconda3\lib\site-packages\numpy\lib\npyio.py", line 1258, in savetxt
    % (str(X.dtype), format))
TypeError: Mismatch between array dtype ('object') and format specifier ('%.18e,%.18e')

与熊猫

In[42]: df = pd.DataFrame(arr)
In[43]: df[:5]
Out[43]: 
                                                   0  \
0  [[30, 29, 198, 198, 197, 197, 197, 197, 197, 1...   
1  [[29, 29, 197, 197, 196, 196, 197, 197, 197, 1...   
2  [[29, 29, 196, 196, 196, 196, 196, 196, 196, 1...   
3  [[29, 29, 196, 196, 196, 196, 196, 196, 196, 1...   
4  [[29, 29, 196, 196, 196, 196, 196, 196, 197, 1...   
                             1  
0  [0, 0, 0, 0, 0, 0, 0, 0, 0]  
1  [1, 0, 0, 0, 0, 0, 0, 0, 0]  
2  [1, 0, 0, 0, 0, 0, 0, 0, 0]  
3  [1, 0, 0, 0, 0, 0, 0, 0, 0]  
4  [1, 0, 0, 0, 0, 0, 0, 0, 0]  
In[44]: df.to_csv("h.csv", index=False)
In[45]: a = pd.read_csv("h.csv", header=None,names =['input', 'output'])
In[46]: a[:5]
Out[46]: 
                                               input  \
0                                                  0   
1  [[ 30  29 198 ..., 149 149 149]\r\n [ 29  29 1...   
2  [[ 29  29 197 ..., 149 149 149]\r\n [ 29  29 1...   
3  [[ 29  29 196 ..., 149 149 149]\r\n [ 29  29 1...   
4  [[ 29  29 196 ..., 149 149 149]\r\n [ 29  29 1...   
                        output  
0                            1  
1  [0, 0, 0, 0, 0, 0, 0, 0, 0]  
2  [1, 0, 0, 0, 0, 0, 0, 0, 0]  
3  [1, 0, 0, 0, 0, 0, 0, 0, 0]  
4  [1, 0, 0, 0, 0, 0, 0, 0, 0]  

当我打印“df[:5]”时,一切看起来都很好,但是在我将它保存到 csv 然后从 csv 读取它之后,它看起来很糟糕,数字之间没有逗号,并且有 '\r\n'列表之间。

我想在读取 csv 文件后看到类似 "df[:5]" 的输出,我该怎么做,有什么问题?

【问题讨论】:

  • csv 用于二维数组,具有整齐的行和列。您展示了一个一维数组,其中包含一个数组和第一个元素的列表。
  • 那么,如何将其存储在 csv 中?
  • 您希望文件是什么样的?
  • 当我阅读时,它应该看起来像 Out[43] 或 Out[39]
  • 我没有问加载后数组应该是什么样子。我想知道文本文件应该是什么样子。您是否了解您在ipython 会话中看到的数组与您可以写入文本文件的内容之间存在差异?

标签: python-3.x csv numpy


【解决方案1】:

Numpy 本身没有“另存为 csv”功能。通常你通过另一个包(如 pandas 或 pickle)保存它。

您看到的“看起来很糟糕”是熊猫格式。加arr = np.array(a) 你又拥有了 numpy 格式。

【讨论】:

  • savetxt 创建一个 csv 兼容文件 - 用于普通的二维数组。
  • 它看起来很糟糕,因为数字之间没有逗号,并且列表之间有 '\r\n'。添加 arr = np.array(a) 不起作用
【解决方案2】:

您的数组是 2d, (1200, 2) 与 object dtype。显然第一列包含二维数组,第二列是列表。

arr[0,0] 是一个二维数组

array([[ 30,  29, 198, ..., 149, 149, 149],
   [ 29,  29, 197, ..., 149, 149, 149],
   [ 29,  29, 197, ..., 149, 149, 149],
   ..., 
   [ 63,  63,  96, ..., 105, 104, 104],
   [ 63,  63,  96, ..., 106, 105, 105],
   [ 77,  77, 217, ..., 217, 217, 217]], dtype=uint8)

您可以轻松地以 csv 格式编写。例如:

In [342]: arr = np.array([[ 30,  29, 198, 149, 149, 149],
     ...:    [ 29,  29, 197, 149, 149, 149],
     ...:    [ 29,  29, 197, 149, 149, 149],
     ...:    [ 63,  63,  96, 105, 104, 104],
     ...:    [ 63,  63,  96, 106, 105, 105],
     ...:    [ 77,  77, 217, 217, 217, 217]], dtype=np.uint8)
     ...:    
     ...:    
In [343]: np.savetxt('arr.txt', arr, delimiter=',', fmt='%4d')

生成一个如下所示的文件:

In [344]: cat arr.txt
  30,  29, 198, 149, 149, 149
  29,  29, 197, 149, 149, 149
  29,  29, 197, 149, 149, 149
  63,  63,  96, 105, 104, 104
  63,  63,  96, 106, 105, 105
  77,  77, 217, 217, 217, 217

阅读savetxt了解更多关于fmt的详细信息。

但完整数组与csv 文件的简单二维布局不兼容。当然你可以写一些更复杂的东西,但是你不能用像np.genfromtxtnp.loadtxt这样的csv阅读器来加载它。那些期望具有明确定义的分隔符的整齐的行和列布局。

In [346]: data = np.genfromtxt('arr.txt',delimiter=',',dtype=None)
In [347]: data
Out[347]: 
array([[ 30,  29, 198, 149, 149, 149],
       [ 29,  29, 197, 149, 149, 149],
       [ 29,  29, 197, 149, 149, 149],
       [ 63,  63,  96, 105, 104, 104],
       [ 63,  63,  96, 106, 105, 105],
       [ 77,  77, 217, 217, 217, 217]])

pandas df 显示两列,一列包含数组,另一列包含列表。但在a 中,第 0 列似乎包含二维数组的字符串表示形式,如换行符所示。你看过h.csv 文件吗?使用csv 的部分原因是人们可以阅读它,而其他程序(如 excel)也可以阅读它。


制作一个和你一样大的数组

In [349]: barr = np.empty((3,2), object)
In [350]: barr[:,0]=[arr,arr,arr]
In [351]: barr[:,1]=[[0,0,0] for _ in range(3)]
In [352]: barr
Out[352]: 
array([[array([[ 30,  29, 198, 149, 149, 149],
       [ 29,  29, 197, 149, 149, 149],
       [ 29,  29, 197, 149, 149, 149],
       [ 63,  63,  96, 105, 104, 104],
       [ 63,  63,  96, 106, 105, 105],
       [ 77,  77, 217, 217, 217, 217]], dtype=uint8),
        list([0, 0, 0])],
       [array([[ 30,  29, 198, 149, 149, 149],
   ...
       [ 77,  77, 217, 217, 217, 217]], dtype=uint8),
        list([0, 0, 0])]], dtype=object)

写成%s 格式,唯一可以处理这样的对象的格式:

In [354]: np.savetxt('barr.txt',barr, delimiter=',',fmt='%s')
In [355]: cat barr.txt
[[ 30  29 198 149 149 149]
 [ 29  29 197 149 149 149]
 [ 29  29 197 149 149 149]
 [ 63  63  96 105 104 104]
 [ 63  63  96 106 105 105]
 [ 77  77 217 217 217 217]],[0, 0, 0]
[[ 30  29 198 149 149 149]
 [ 29  29 197 149 149 149]
 [ 29  29 197 149 149 149]
 [ 63  63  96 105 104 104]
 [ 63  63  96 106 105 105]
 [ 77  77 217 217 217 217]],[0, 0, 0]
[[ 30  29 198 149 149 149]
 [ 29  29 197 149 149 149]
 [ 29  29 197 149 149 149]
 [ 63  63  96 105 104 104]
 [ 63  63  96 106 105 105]
 [ 77  77 217 217 217 217]],[0, 0, 0]

这不是一个有效的csv 文件。它是文本,但带有 [] 和不同的行长,标准的csv 文件阅读器都无法处理它。


像使用 pandas 一样保存该数组,我得到:

In [364]: cat pdbarr.txt
0,1
"[[ 30  29 198 149 149 149]
 [ 29  29 197 149 149 149]
 [ 29  29 197 149 149 149]
 [ 63  63  96 105 104 104]
 [ 63  63  96 106 105 105]
 [ 77  77 217 217 217 217]]","[0, 0, 0]"
"[[ 30  29 198 149 149 149]
 [ 29  29 197 149 149 149]
 [ 29  29 197 149 149 149]
 [ 63  63  96 105 104 104]
 [ 63  63  96 106 105 105]
 [ 77  77 217 217 217 217]]","[0, 0, 0]"
"[[ 30  29 198 149 149 149]
 [ 29  29 197 149 149 149]
 [ 29  29 197 149 149 149]
 [ 63  63  96 105 104 104]
 [ 63  63  96 106 105 105]
 [ 77  77 217 217 217 217]]","[0, 0, 0]"

注意所有的引号 - 它将那些组件数组和列表写为字符串。同样,不是有效的csv

【讨论】:

  • 我的 numpy 数组不喜欢它。它有一个 numpy 数组和一个列表。所以'np.savetxt'不起作用。我写了关于它的错误。
  • savetxt 可以使用字符串格式:np.savetxt('arr.txt', arr, delimiter=',', fmt='%s')。至少它应该运行没有错误。但您可能不会喜欢生成的文件。
猜你喜欢
  • 2019-03-05
  • 2016-08-01
  • 2018-08-23
  • 2017-08-02
  • 2016-12-09
  • 2013-12-16
  • 2020-10-24
  • 1970-01-01
  • 2020-07-09
相关资源
最近更新 更多