我是nympy的新手,我正在尝试使用以下代码将tab(\ t)分隔的文本文件读入numpy数组矩阵:
train_data = np.genfromtxt('training.txt', dtype=None, delimiter='\t')
文件内容:
38 Private 215646 HS-grad 9 Divorced Handlers-cleaners Not-in-family White Male 0 0 40 United-States <=50K
53 Private 234721 11th 7 Married-civ-spouse Handlers-cleaners Husband Black Male 0 0 40 United-States <=50K
30 State-gov 141297 Bachelors 13 Married-civ-spouse Prof-specialty Husband Asian-Pac-Islander Male 0 0 40 India >50K
我期望的是形状(3,15)的二维阵列矩阵
但是使用上面的代码我只得到一个单行数组(3,)
我不确定为什么每行的15个字段都没有分配一列。
我也试过使用numpy的loadtxt()但它无法处理我的数据类型转换,即使我给dtype = None它试图将字符串转换为默认浮点类型并且失败了。
尝试过的代码:
train_data = np.loadtxt('try.txt', dtype=None, delimiter='\t')
Error:
ValueError: could not convert string to float: State-gov
任何指针?
由于
答案 0 :(得分:4)
实际上,这里的问题是np.genfromtxt
和np.loadtxt
如果dtype是结构化的(即,有多种类型),则返回structured array。您的数组报告的形状为(3,)
,因为从技术上讲,它是一个“记录”的1d数组。这些“记录”包含您的所有列,但您可以访问所有数据,就像它是2d一样。
您正确加载它:
In [82]: d = np.genfromtxt('tmp',dtype=None)
正如您所报告的那样,它具有1d形状:
In [83]: d.shape
Out[83]: (3,)
但你的所有数据都在那里:
In [84]: d
Out[84]:
array([ (38, 'Private', 215646, 'HS-grad', 9, 'Divorced', 'Handlers-cleaners', 'Not-in-family', 'White', 'Male', 0, 0, 40, 'United-States', '<=50K'),
(53, 'Private', 234721, '11th', 7, 'Married-civ-spouse', 'Handlers-cleaners', 'Husband', 'Black', 'Male', 0, 0, 40, 'United-States', '<=50K'),
(30, 'State-gov', 141297, 'Bachelors', 13, 'Married-civ-spouse', 'Prof-specialty', 'Husband', 'Asian-Pac-Islander', 'Male', 0, 0, 40, 'India', '>50K')],
dtype=[('f0', '<i8'), ('f1', 'S9'), ('f2', '<i8'), ('f3', 'S9'), ('f4', '<i8'), ('f5', 'S18'), ('f6', 'S17'), ('f7', 'S13'), ('f8', 'S18'), ('f9', 'S4'), ('f10', '<i8'), ('f11', '<i8'), ('f12', '<i8'), ('f13', 'S13'), ('f14', 'S5')])
数组的dtype
结构如下:
In [85]: d.dtype
Out[85]: dtype([('f0', '<i8'), ('f1', 'S9'), ('f2', '<i8'), ('f3', 'S9'), ('f4', '<i8'), ('f5', 'S18'), ('f6', 'S17'), ('f7', 'S13'), ('f8', 'S18'), ('f9', 'S4'), ('f10', '<i8'), ('f11', '<i8'), ('f12', '<i8'), ('f13', 'S13'), ('f14', 'S5')])
您仍然可以使用dtype中指定的名称访问“列”(称为字段):
In [86]: d['f0']
Out[86]: array([38, 53, 30])
In [87]: d['f1']
Out[87]:
array(['Private', 'Private', 'State-gov'],
dtype='|S9')
给字段指定正确的名称会更方便:
In [104]: names = "age,military,id,edu,a,marital,job,fam,ethnicity,gender,b,c,d,country,income"
In [105]: d = np.genfromtxt('tmp',dtype=None, names=names)
因此,您现在可以访问'age'
字段等:
In [106]: d['age']
Out[106]: array([38, 53, 30])
In [107]: d['income']
Out[107]:
array(['<=50K', '<=50K', '>50K'],
dtype='|S5')
或35岁以下人口的收入
In [108]: d[d['age'] < 35]['income']
Out[108]:
array(['>50K'],
dtype='|S5')
超过35
In [109]: d[d['age'] > 35]['income']
Out[109]:
array(['<=50K', '<=50K'],
dtype='|S5')
答案 1 :(得分:1)
我不认为Numpy数组在单个数组中处理不同的数据类型。可以做的是将整个数组作为字符串加载,然后根据需要将必要的列转换为数字
# Load data as strings
train_data = np.loadtxt('try.txt', dtype=np.str, delimiter='\t')
# Convert numeric strings into integers
first_col = train_data[:,0].astype(np.int)
third_col = train_data[:,2].astype(np.int)
答案 2 :(得分:1)
抱歉,我误解了你原来的问题:
我期望的是形状(3,15)的二维阵列矩阵
但是使用上面的代码我只得到一个单行数组(3,)
我认为你误解了np.genfromtxt()
将会返回的内容。在这种情况下,它会尝试推断文本文件中每个“列”的类型,然后返回structured / "record" array。每行将包含多个字段(f0...f14
),每个字段都可以包含与文本文件中“列”对应的不同类型的值。您可以按名称索引特定字段,例如data['f0']
。
你只是不能拥有(3,15)
numpy异构类型数组。您可以拥有(3,15)
齐次字符串数组,例如:
>>> string_data = np.genfromtext('test', dtype=str, delimiter='\t')
>>> print string_data.shape
(3, 15)
当然,您可以手动将列转换为您想要的任何类型,如@ DrRobotNinja的答案。但是你也可以让numpy为你创建一个结构化数组,然后按字段对其进行索引并将列分配给新数组。