我有一个文本文件:
0.01 1 0.1 1 10 100 a
0.02 3 0.2 2 20 200 b
0.03 2 0.3 3 30 300 c
0.04 1 0.4 4 40 400 d
我将其作为列表A
读取,然后转换为numpy数组,即:
>>> A
array([['0.01', '1', '0.1', '1', '10', '100', 'a'],
['0.02', '3', '0.2', '2', '20', '200', 'b'],
['0.03', '2', '0.3', '3', '30', '300', 'c'],
['0.04', '1', '0.4', '4', '40', '400', 'd']],
dtype='|S4')
我只想提取一个由B
组成的子数组A
,只要它的第4个条目低于30,就应该看起来像这样:
B = array([['0.01', '1', '0.1', '1', '10', '100', 'a'],
['0.02', '3', '0.2', '2', '20', '200', 'b']])
在处理数组时,我通常只做B = A[A[:,4]<30]
,但在这种情况下(可能是由于存在我从未使用过的字符/字符串),它不起作用,给出我这个:
>>> A[A[:,4]<30]
array(['0.01', '1', '0.1', '1', '10', '100', 'a'],
dtype='|S4')
我无法弄清楚原因。我没有处理我的代码,我不认为我可以将所有这些转换为结构或词典:任何建议用numpy数组做这个吗?非常感谢你提前!
答案 0 :(得分:2)
您必须将int
与int
A[A[:,4].astype(int)<30]
或str
至str
A[A[:,4]<'30']
但是,请注意后者可以在您的特定示例中使用,但通常不会工作,因为您正在比较str
顺序(例如,'110' < '30'
返回True
,但110 < 30
返回False
)
numpy
会推断出你的元素&#39;您的数据中的类型。在这种情况下,它将type = '|S4'
归因于您的元素,这意味着它们是长度为4的字符串。这可能是基础C
代码的结果(它增强了numpy
&#39}性能)要求元素具有固定类型。
为了说明这种差异,请检查以下代码:
>>> np.array([['0.01', '1', '0.1', '1', '10', '100', 'a']])
array(['0.01', '1', '0.1', '1', '10', '100', 'a'], dtype='|S4')
长度为4的字符串的推断类型,即元素的最大长度(在elem 0.01
中)。现在,如果您明确地定义它来保存常规类型对象,它将执行您想要的操作
>>> np.array([[0.01, 1, 0.1, 1, 10, 100, 'a']], dtype=object)
array([0.01, 1, 0.1, 1, 10, 100, 'a'], dtype=object)
并且您的代码A[A[:,4]<30]
可以正常运行。
有关详细信息, this 是一个非常完整的指南
答案 1 :(得分:1)
In [86]: txt='''0.01 1 0.1 1 10 100 a
...: 0.02 3 0.2 2 20 200 b
...: 0.03 2 0.3 3 30 300 c
...: 0.04 1 0.4 4 40 400 d'''
In [87]: A = np.genfromtxt(txt.splitlines(), dtype=str)
In [88]: A
Out[88]:
array([['0.01', '1', '0.1', '1', '10', '100', 'a'],
['0.02', '3', '0.2', '2', '20', '200', 'b'],
['0.03', '2', '0.3', '3', '30', '300', 'c'],
['0.04', '1', '0.4', '4', '40', '400', 'd']], dtype='<U4')
In [89]: A[:,4]
Out[89]: array(['10', '20', '30', '40'], dtype='<U4')
genfromtxt
,默认情况下尝试制作浮点数。但在这种情况下,字符列将为nan
。相反,我指定了str
dtype。
因此,数字测试需要将列转换为数字:
In [90]: A[:,4].astype(int)
Out[90]: array([10, 20, 30, 40])
In [91]: A[:,4].astype(int)<30
Out[91]: array([ True, True, False, False])
在这种情况下,字符串比较也有效:
In [99]: A[:,4]<'30'
Out[99]: array([ True, True, False, False])
或者,如果我们使用dtype = None,它会按列推断dtype并生成结构化数组:
In [93]: A1 = np.genfromtxt(txt.splitlines(), dtype=None,encoding=None)
In [94]: A1
Out[94]:
array([(0.01, 1, 0.1, 1, 10, 100, 'a'), (0.02, 3, 0.2, 2, 20, 200, 'b'),
(0.03, 2, 0.3, 3, 30, 300, 'c'), (0.04, 1, 0.4, 4, 40, 400, 'd')],
dtype=[('f0', '<f8'), ('f1', '<i8'), ('f2', '<f8'), ('f3', '<i8'), ('f4', '<i8'), ('f5', '<i8'), ('f6', '<U1')])
现在我们可以按名称选择一个字段,并测试它:
In [95]: A1['f4']
Out[95]: array([10, 20, 30, 40])
无论哪种方式,我们都可以根据True / False掩码或相应的行索引选择行:
In [96]: A[[0,1],:]
Out[96]:
array([['0.01', '1', '0.1', '1', '10', '100', 'a'],
['0.02', '3', '0.2', '2', '20', '200', 'b']], dtype='<U4')
In [98]: A1[[0,1]] # A1 is 1d
Out[98]:
array([(0.01, 1, 0.1, 1, 10, 100, 'a'), (0.02, 3, 0.2, 2, 20, 200, 'b')],
dtype=[('f0', '<f8'), ('f1', '<i8'), ('f2', '<f8'), ('f3', '<i8'), ('f4', '<i8'), ('f5', '<i8'), ('f6', '<U1')])