如何在Python中从数组中读取不包含特定列的数据
我有一个numpy数组,它的类型是object(实际上是各种数据类型的列表)。所以它形成了一个二维数组,因为我有一个列表的数组(?)。我想把这个数组的每一行和某些特定的列复制到另一个数组里。我是从一个csv文件里存储数据到这个数组的。这个csv文件包含了几个字段(列)和大量的行。下面是我用来把数据存储到数组中的代码。
data = np.zeros((401125,), dtype = object)
for i, row in enumerate(csv_file_object):
data[i] = row
数据大致可以描述如下
column1 column2 column3 column4 column5 ....
1 none 2 'gona' 5.3
2 34 2 'gina' 5.5
3 none 2 'gana' 5.1
4 43 2 'gena' 5.0
5 none 2 'guna' 5.7
..... .... ..... ..... ....
..... .... ..... ..... ....
..... .... ..... ..... ....
中间有一些我不想要的字段,我想把它们去掉。假设我不想要第三列。那我该怎么从我的数组中去掉这一列呢?或者只把相关的列复制到另一个数组里呢?
3 个回答
你可以使用范围选择的方法。比如,要删除第三列,你可以这样做:
data = np.zeros((401125,), dtype = object)
for i, row in enumerate(csv_file_object):
data[i] = row[:2] + row[3:]
这样做是可以的,前提是你的csv_file_object返回的是列表。如果你使用的是一个简单的file
对象,比如用csv_file_object = open("file.cvs")
创建的,那么在你的循环中需要加上split
:
data = np.zeros((401125,), dtype = object)
for i, row in enumerate(csv_file_object):
row = row.split()
data[i] = row[:2] + row[3:]
假设你正在读取CSV文件的每一行,并把它们放进一个numpy
数组里,最简单也是最好的方法就是在数据进入数组之前先处理一下数据,就像Maciek D.的回答所示。如果你想做一些比“删除第三列”更复杂的操作,你可以用类似[value for i, value in enumerate(row) if i not in (1, 3, 5)]
的写法,但大体思路是一样的。
不过,如果你已经把数组导入了,想在之后进行筛选,你可能需要用到take
或者delete
:
>>> d=np.array([[1,None,2,'gona',5.3],[2,34,2,'gina',5.5],[3,None,2,'gana',5.1],[4,43,2,'gena',5.0],[5,None,2,'guna',5.7]])
>>> np.delete(d, 2, 1)
array([[1, None, gona, 5.3],
[2, 34, gina, 5.5],
[3, None, gana, 5.1],
[4, 43, gena, 5.0],
[5, None, guna, 5.7]], dtype=object)
>>> np.take(d, [0, 1, 3, 4], 1)
array([[1, None, gona, 5.3],
[2, 34, gina, 5.5],
[3, None, gana, 5.1],
[4, 43, gena, 5.0],
[5, None, guna, 5.7]], dtype=object)
对于简单的“删除第三列”这种情况,使用delete
更合适;而对于更复杂的情况,使用take
可能更合理。
如果你还不知道怎么导入数据,你可以使用内置的csv
模块,参考Maciek D.的代码边处理边导入,或者使用类似pandas.read_csv
的方法,在导入后再处理结果,就像root的回答所示。
不过,最开始使用numpy
的本地数据格式可能会更好,而不是CSV。
可以使用pandas这个库。而且我觉得,对于你这种不同类型的数据,pandas.DataFrame
可能更合适。
from StringIO import StringIO
from pandas import *
import numpy as np
data = """column1 column2 column3 column4 column5
1 none 2 'gona' 5.3
2 34 2 'gina' 5.5
3 none 2 'gana' 5.1
4 43 2 'gena' 5.0
5 none 2 'guna' 5.7"""
data = StringIO(data)
print read_csv(data, delim_whitespace=True).drop('column3',axis =1)
输出:
column1 column2 column4 column5
0 1 none 'gona' 5.3
1 2 34 'gina' 5.5
2 3 none 'gana' 5.1
3 4 43 'gena' 5.0
4 5 none 'guna' 5.7
如果你需要一个数组而不是DataFrame,可以使用to_records()
这个方法:
df.to_records(index = False)
#output:
rec.array([(1L, 'none', "'gona'", 5.3),
(2L, '34', "'gina'", 5.5),
(3L, 'none', "'gana'", 5.1),
(4L, '43', "'gena'", 5.0),
(5L, 'none', "'guna'", 5.7)],
dtype=[('column1', '<i8'), ('column2', '|O4'),
('column4', '|O4'), ('column5', '<f8')])