【问题标题】:Python 3 Numpy File CSV convert to narrayPython 3 Numpy 文件 CSV 转换为数组
【发布时间】:2017-02-13 19:16:12
【问题描述】:

我有一个ndarray,我正在尝试从 CSV 文件中读取它。 我可以通过numpy 从文件中读取它,但无法获得我想要的结构;而不是二维数组,我有一个元组数组

作为 MCVE:我没有像 DataSet1 这样的二维数组,而是 DataSet2

dataset=numpy.array([
        ["abc ",3000.0,1],
        ["def",3650.0,1],
        ["xyz",3000.0,2]        
        ])
print("DataSet1\n",dataset)
print("DataSet1-Shape\n",dataset.shape)


dataset2=numpy.array([])

dataset2 = np.genfromtxt('file.csv', delimiter=",",dtype='S32,float,int')

print("DataSet2\n",dataset2)
print("DataSet2-Shape\n",dataset2.shape)

输出是:

DataSet1
 [['abc ' '3000.0' '1']
 ['def' '3650.0' '1']
 ['xyz' '3000.0' '2']]
DataSet1-Shape
 (3, 3)
DataSet2
 [(b'"fabc"', 3000.0, 1) (b'"fdef"', 3650.0, 1) (b'"ghi"', 3000.0, 2)]
DataSet2-Shape
 (3,)

我希望 DataSet2 成为 DataSet1 的 2D。

CSV 文件内容:

"fabc",3000.0,1
"fdef",3650.0,1
"ghi",3000.0,2

【问题讨论】:

  • 能否包含 csv 的内容?
  • 目前 csv 是 3 行,但会增长:"fabc",3000.0,1 "fdef",3650.0,1 "ghi",3000.0,2
  • 请编辑您的问题以包含此内容(我猜也缺少 \n 个字符)
  • 所以你很高兴Dataset1 只是字符串?您可以像这样直接加载 CSV。试试 dtype str.

标签: arrays python-3.x csv numpy multidimensional-array


【解决方案1】:

使用列表理解并将元组转换为带有np.array([list(tup) for tup in dataset2]) 的列表应该可以工作:

>>> np.array([list(tup) for tup in dataset2])
array([['"fabc"', '3000.0', '1'],
       ['"fdef"', '3650.0', '1'],
       ['"ghi"', '3000.0', '2']], 
      dtype='|S6')
>>> np.array([list(tup) for tup in dataset2]).shape
(3, 3)

还要注意你的dataset2 = numpy.array([]) 是无用的,因为dataset2 在下一行被覆盖了。 编辑:[list(tup) for tup in dataset2]map(list, dataset2) 的结果

对于 np 数组中的混合类型,请参阅Store different datatypes in one NumPy array?;我建议你改用pandas.DataFrame

【讨论】:

  • 几乎可以工作...除了每个字段值现在都是一个字符串: [[b'"fabc"' b'3000.0' b'1'] [b'"fdef"' b'3650.0' b'1'] [b'"ghi"' b'3000.0' b'2']]
  • numpy 数组只能有一种类型,我认为。如果您想要混合类型,可以使用 pandas.DataFrame(只需执行 df=pd.DataFrame(your_array))
  • dataset2.tolist() 与您的列表理解一样有效。 np.array 将元组视为列表 - 除非给定复合 dtype。
【解决方案2】:

您的复合 dtype 将文件加载为具有 3 个字段的一维数组

In [195]: data=np.genfromtxt('stack39872346.txt',delimiter=',',dtype='S32,float,int')
In [196]: data
Out[196]: 
array([(b'"fabc"', 3000.0, 1), (b'"fdef"', 3650.0, 1),
       (b'"ghi"', 3000.0, 2)], 
      dtype=[('f0', 'S32'), ('f1', '<f8'), ('f2', '<i4')])
In [197]: data.shape
Out[197]: (3,)
In [198]: data.dtype
Out[198]: dtype([('f0', 'S32'), ('f1', '<f8'), ('f2', '<i4')])

您的 Dataset1 是 2d 字符串 dtype:

In [207]: Dataset1
Out[207]: 
array([['abc ', '3000.0', '1'],
       ['def', '3650.0', '1'],
       ['xyz', '3000.0', '2']], 
      dtype='<U6')

将复合数据类型转换为简单数据类型有点棘手。可以使用astype 完成。但也许使用data 的列表版本作为中介更简单。

In [203]: data.tolist()
Out[203]: [(b'"fabc"', 3000.0, 1), (b'"fdef"', 3650.0, 1), (b'"ghi"', 3000.0, 2)]
In [204]: np.array(data.tolist())
Out[204]: 
array([[b'"fabc"', b'3000.0', b'1'],
       [b'"fdef"', b'3650.0', b'1'],
       [b'"ghi"', b'3000.0', b'2']], 
      dtype='|S6')

np.array 已读取元组列表,并创建了一个最常见类型的二维数组,S6(Py3 字节串)

现在很容易用astype转换成unicode字符串:

In [205]: np.array(data.tolist()).astype("U6")
Out[205]: 
array([['"fabc"', '3000.0', '1'],
       ['"fdef"', '3650.0', '1'],
       ['"ghi"', '3000.0', '2']], 
      dtype='<U6')

这类似于Dataset1,只是第一列是双引号。

我可以通过指定dtype 跳过最后一个astypenp.array(data.tolist(),dtype=str)

更好的是,告诉genfromtxt

np.genfromtxt('stack39872346.txt',delimiter=',',dtype=str)

原始复合 dtype 的一个好处是您可以将数字字段作为数字访问:

In [214]: data['f1']
Out[214]: array([ 3000.,  3650.,  3000.])
In [215]: Dataset1[:,1]
Out[215]: 
array(['3000.0', '3650.0', '3000.0'], 
      dtype='<U6')

我还没有解决双引号。 csv 阅读器可以剥离这些; genfromtxt 没有。虽然幸运的是引号中没有分隔符,所以我可以写一个converter,在genfromtxt 读取期间将它们去掉。

===================

def foo(astr):
    return astr[1:-1] # crude dequote

In [223]: data=np.genfromtxt('stack39872346.txt',delimiter=',',
     dtype='U6,float,int', converters={0:foo})
In [224]: data
Out[224]: 
array([('fabc', 3000.0, 1), 
       ('fdef', 3650.0, 1), 
       ('ghi', 3000.0, 2)], 
      dtype=[('f0', '<U6'), ('f1', '<f8'), ('f2', '<i4')])

In [225]: np.array(data.tolist())
Out[225]: 
array([['fabc', '3000.0', '1'],
       ['fdef', '3650.0', '1'],
       ['ghi', '3000.0', '2']], 
      dtype='<U6')

看起来我在加载 converter 时必须使用复合 dtype。

【讨论】:

    猜你喜欢
    • 2018-02-18
    • 2017-01-15
    • 2020-02-22
    • 2017-11-02
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 2013-05-05
    • 2021-08-24
    相关资源
    最近更新 更多