使用numpy从genfromtxt中排除列

时间:2016-03-18 18:23:36

标签: python numpy

是否可以使用genfromtxt库中的numpy排除所有字符串列?

我有一个csv文件,其中包含来自 机器学习网站的此类数据。

antelope,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,1

目前使用我的设置np.genfromtxt(path, dtype=float, names=None,delimiter=','),它将字符串标记为nan,这有意义,但我想排除所有字符串列。

我知道有usecols=(1,2)参数,但这需要我指定我需要使用的这个或每个数据集。我更喜欢"排除"方法而不是包含方法。

我应该使用不同的方法或者自己处理每一行吗?

2 个答案:

答案 0 :(得分:1)

pandas有一个DataFrame.select_dtypes方法,可以让你轻松地完成这项工作。您可以直接将数据导入DataFrame(如下例所示),也可以使用各种读取方法之一(例如pd.read_csv()):

In [21]: import pandas as pd

In [22]: df = pd.DataFrame({'a': [1,2,3,4,5], 'b': ['a','b','c','d','e'], 'c': [1.1, 2.2, 3.3, 4.4, 5.5]})

In [23]: df
Out[23]:
   a  b    c
0  1  a  1.1
1  2  b  2.2
2  3  c  3.3
3  4  d  4.4
4  5  e  5.5

In [24]: df.select_dtypes([int, float])
Out[24]:
   a    c
0  1  1.1
1  2  2.2
2  3  3.3
3  4  4.4
4  5  5.5

答案 1 :(得分:1)

阅读后,您可以使用nan过滤掉列。

In [52]: txt=b'antelope,1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,1'
In [53]: txt=[txt,txt]
In [54]: A=np.genfromtxt(txt, dtype=float, names=None,delimiter=',')
In [55]: A
Out[55]: 
array([[ nan,   1.,   0.,   0.,   1.,   0.,   0.,   0.,   1.,   1.,   1.,
          0.,   0.,   4.,   1.,   0.,   1.,   1.],
       [ nan,   1.,   0.,   0.,   1.,   0.,   0.,   0.,   1.,   1.,   1.,
          0.,   0.,   4.,   1.,   0.,   1.,   1.]])

所有行中包含nan的列;或者我可以将.any用于任何nan的列。其他测试也是可能的。

In [56]: ind=np.isnan(A).all(axis=0)
In [57]: ind
Out[57]: 
array([ True, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False], dtype=bool)
In [58]: A[:,~ind]
Out[58]: 
array([[ 1.,  0.,  0.,  1.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  4.,
         1.,  0.,  1.,  1.],
       [ 1.,  0.,  0.,  1.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  4.,
         1.,  0.,  1.,  1.]])

另一个想法是使用dtype=None读取文件一次,让genfromtxt为每列选择dtype。得到的化合物dtype可以过滤以找到所需类型的列。

In [118]: A=np.genfromtxt(txt, dtype=None, names=None,delimiter=',')
In [119]: ind=[i for i, d in enumerate(A.dtype.descr) if d[1]=='<i4']
In [120]: A=np.genfromtxt(txt, dtype=None, names=None,delimiter=',',usecols=ind) 
In [121]: A
Out[121]: 
array([[1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1],
       [1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1]])

也可以过滤dtype以收集类型正确的列名

In [128]: A=np.genfromtxt(txt, dtype=None, names=None,delimiter=',')
In [129]: ind=[d[0] for d in A.dtype.descr if d[1]=='<i4']
In [130]: A[ind]
Out[130]: 
array([(1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1),
       (1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 4, 1, 0, 1, 1)], 
      dtype=[('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4'), ('f4', '<i4'), ('f5', '<i4'), ('f6', '<i4'), ('f7', '<i4'), ('f8', '<i4'), ('f9', '<i4'), ('f10', '<i4'), ('f11', '<i4'), ('f12', '<i4'), ('f13', '<i4'), ('f14', '<i4'), ('f15', '<i4'), ('f16', '<i4'), ('f17', '<i4')])

虽然将这个结构化数组合并到一个带有单个dtype(int)的二维数组中,但是有点痛苦(如果需要,我可以进入细节)。