Python 3 Numpy文件CSV转换为数组



我有一个ndarray,我正试图从CSV文件中读取。我可以通过numpy从文件中读取它,但不能得到我想要的结构;这里不是二维数组而是元组数组

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

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

dataset2=numpy.array([])
dataset2 = np.genfromtxt('file.csv', delimiter=",",dtype='S32,float,int')
print("DataSet2n",dataset2)
print("DataSet2-Shapen",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

使用列表推导式并使用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数组中的混合类型,请参见在一个NumPy数组中存储不同的数据类型?;我建议你用pandas.DataFrame代替。

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

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读取了元组列表,并创建了一个最常见类型的2d数组,S6 (Py3 bytestring)

现在很容易用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来跳过最后一个astype: np.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')

它看起来像我必须使用复合dtype时加载converter

相关内容

  • 没有找到相关文章

最新更新