我有一个制表符分隔的csv数据集如下:
1 2 3 4 5 6 [0, 1, 2, 3, 4, 5]
3 1 2 6 4 5 [2, 0, 1, 5, 3, 4]
7 8 9 10 11 6 [0, 1, 2, 3, 4, 5]
10 11 9 8 7 6 [3, 4, 2, 1, 0, 5]
12 13 4 14 15 6 [0, 1, 2, 3, 4, 5]
13 4 14 12 15 6 [1, 2, 3, 0, 4, 5]
16 17 18 19 20 6 [0, 1, 2, 3, 4, 5]
6 18 20 17 16 19 [5, 2, 4, 1, 0, 3]
7 21 22 23 24 6 [0, 1, 2, 3, 4, 5]
23 6 21 7 22 24 [3, 5, 1, 0, 2, 4]
25 7 21 22 23 6 [0, 1, 2, 3, 4, 5]
6 21 7 22 25 23 [5, 2, 1, 3, 0, 4]
16 26 3 27 28 6 [0, 1, 2, 3, 4, 5]
26 6 27 3 28 16 [1, 5, 3, 2, 4, 0]
7 29 24 30 31 6 [0, 1, 2, 3, 4, 5]
30 24 6 7 29 31 [3, 2, 5, 0, 1, 4]
32 33 13 34 35 36 [0, 1, 2, 3, 4, 5]
34 32 36 35 13 33 [3, 0, 5, 4, 2, 1]
7 37 38 39 40 6 [0, 1, 2, 3, 4, 5]
39 38 40 6 37 7 [3, 2, 4, 5, 1, 0]
7 41 42 43 44 6 [0, 1, 2, 3, 4, 5]
41 6 44 43 42 7 [1, 5, 4, 3, 2, 0]
7 45 46 47 48 6 [0, 1, 2, 3, 4, 5]
6 47 45 7 46 48 [5, 3, 1, 0, 2, 4]
49 2 50 51 52 6 [0, 1, 2, 3, 4, 5]
当我想将这样的csv文件导入numpy数组时,如下所示;
dataset = numpy.loadtxt('dataset/demo_dataset.csv', delimiter='\t', dtype='str')
我获得了一个(25,)
形状的numpy数组。
我想将这个csv文件导入两个名为X和Y的numpy数组。
X将包含前6列,Y将包括最后一列作为列表值,而不是str。
我该如何管理?
答案 0 :(得分:3)
我设法通过自定义方法实现了这一目标:
import numpy
with open('dataset/demo_dataset.csv', 'r') as fin:
lines = fin.readlines()
# remove '\n' characters
clean_lines = [l.strip('\n') for l in lines]
# split on tab so that we get lists from strings
A = [cl.split('\t') for cl in clean_lines]
# get lists of ints instead of lists of strings
X = [map(int, row[0:6]) for row in A]
# last column in Y
Y = [row[6] for row in A]
# convert string to int values
for i in xrange(len(Y)):
Y[i] = map(int, Y[i].strip('[]').split(','))
答案 1 :(得分:2)
使用genfromtxt
的一些选项:
In [1047]: txt=b"""7\t8\t9\t10\t11\t6\t [0, 1, 2, 3, 4, 5]"""
In [1048]: txt=[txt,txt,txt]
In [1049]: txt
Out[1049]:
[b'7\t8\t9\t10\t11\t6\t [0, 1, 2, 3, 4, 5]',
b'7\t8\t9\t10\t11\t6\t [0, 1, 2, 3, 4, 5]',
b'7\t8\t9\t10\t11\t6\t [0, 1, 2, 3, 4, 5]']
加载为默认浮点数 - 最后一列为nan
:
In [1050]: np.genfromtxt(txt,delimiter='\t')
Out[1050]:
array([[ 7., 8., 9., 10., 11., 6., nan],
[ 7., 8., 9., 10., 11., 6., nan],
[ 7., 8., 9., 10., 11., 6., nan]])
作为字符串
In [1051]: np.genfromtxt(txt,delimiter='\t',dtype='str')
Out[1051]:
array([['7', '8', '9', '10', '11', '6', ' [0, 1, 2, 3, 4, 5]'],
['7', '8', '9', '10', '11', '6', ' [0, 1, 2, 3, 4, 5]'],
['7', '8', '9', '10', '11', '6', ' [0, 1, 2, 3, 4, 5]']],
dtype='<U19')
让它决定最佳拟合 - 结果是一个结构化数组,带有int字段和一个字符串字段。
In [1052]: np.genfromtxt(txt,delimiter='\t',dtype=None)
Out[1052]:
array([(7, 8, 9, 10, 11, 6, b' [0, 1, 2, 3, 4, 5]'),
(7, 8, 9, 10, 11, 6, b' [0, 1, 2, 3, 4, 5]'),
(7, 8, 9, 10, 11, 6, b' [0, 1, 2, 3, 4, 5]')],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4'), ('f4', '<i4'), ('f5', '<i4'), ('f6', 'S19')])
In [1053]: _['f6']
Out[1053]:
array([b' [0, 1, 2, 3, 4, 5]', b' [0, 1, 2, 3, 4, 5]',
b' [0, 1, 2, 3, 4, 5]'],
dtype='|S19')
优化dtype - 一个字段有6列,另一个字符串:
In [1055]: np.genfromtxt(txt,delimiter='\t',dtype='6int,S20')
Out[1055]:
array([([7, 8, 9, 10, 11, 6], b' [0, 1, 2, 3, 4, 5]'),
([7, 8, 9, 10, 11, 6], b' [0, 1, 2, 3, 4, 5]'),
([7, 8, 9, 10, 11, 6], b' [0, 1, 2, 3, 4, 5]')],
dtype=[('f0', '<i4', (6,)), ('f1', 'S20')])
第一个字段是您想要的X
;最后一个字段中的字符串需要进一步处理(根据您的其他问题):
In [1060]: _['f0']
Out[1060]:
array([[ 7, 8, 9, 10, 11, 6],
[ 7, 8, 9, 10, 11, 6],
[ 7, 8, 9, 10, 11, 6]])
In [1061]: __['f1']
Out[1061]:
array([b' [0, 1, 2, 3, 4, 5]', b' [0, 1, 2, 3, 4, 5]',
b' [0, 1, 2, 3, 4, 5]'],
最后一个字段可以@chefarov
转换为Y
变量。
想想,我可以通过另一次调用genfromtxt
来处理该字符串字段。我仍然需要删除[]
。
In [1101]: data=np.genfromtxt(txt,delimiter='\t',dtype='6int,S20')
In [1102]: data['f1']
Out[1102]:
array([b'[0, 1, 2, 3, 4, 5]', b'[0, 1, 2, 3, 4, 5]', b'[0, 1, 2, 3, 4, 5]'],
dtype='|S20')
In [1103]: np.genfromtxt([l.strip(b'[]') for l in data['f1']],delimiter=',',dtype=int)
Out[1103]:
array([[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5]])
我建议,在其他情况下,预处理行以删除引号,括号和问题分隔符。 genfromtxt
接受来自其中的任何内容的输入。但在这种情况下,所需的处理大部分是@chefarov
建议的内容 - 减去int
次转化。
genfromtxt
也接受转换器,但我在其他问题中发现转换器无法将一个字段更改为多个字段。
同样genfromtxt
遍历文件行,并对每个文件行进行解码并收集列表中的值。因此,定制阅读器没有任何速度优势。
答案 2 :(得分:1)
如果你使用pandas
,有一种(可以说)更简单的方法来读取数据。首先,可以构造一个pandas.DataFrame
实例,我们可以将自定义函数应用到它的最后一列将字符串元素转换为np.ndarray
类型:
import pandas as pd
import numpy as np
df = pd.read_table('dataset/demo_dataset.csv', delimiter='\t', names='abcdefg')
convert = lambda a: np.fromstring(a[1:-1], count = a.count(',') + 1, sep = ', ', dtype=int)
df.g = df.g.apply(convert)
构建混合数据帧后,X
和Y
可以简单的方式提取为数组:
X = df.values[:, :-1].astype(int)
Y = np.vstack(df.values[:, -1])