使用Python删除列中特定值的行
我该怎么删除第五列中值为'0'的行呢?
或者更好的是,我们能不能选择一个范围(比如,删除第五列中值在-50到30之间的行)?
数据看起来是这样的:
0 4028.44 4544434.50 -6.76 -117.00 0.0002 0.12
0 4028.50 3455014.50 -5.86 0 0.0003 0.39
0 7028.56 4523434.50 -4.95 -137.00 0.0005 0.25
0 8828.62 4543414.50 -3.05 0 0.0021 0.61
0 4028.44 4544434.50 -6.76 -107.00 0.0002 0.12
0 4028.50 3455014.50 -5.86 -11.00 0.0003 0.39
0 7028.56 4523434.50 -4.95 -127.00 0.0005 0.25
0 8828.62 4543414.50 -3.05 0 0.0021 0.61
3 个回答
1
假设你的数据存储在一个普通的文本文件里,内容像这样:
$ cat data.txt
0 4028.44 4544434.50 -6.76 -117.00 0.0002 0.12
0 4028.50 3455014.50 -5.86 0 0.0003 0.39
0 7028.56 4523434.50 -4.95 -137.00 0.0005 0.25
0 8828.62 4543414.50 -3.05 0 0.0021 0.61
0 4028.44 4544434.50 -6.76 -107.00 0.0002 0.12
0 4028.50 3455014.50 -5.86 -11.00 0.0003 0.39
0 7028.56 4523434.50 -4.95 -127.00 0.0005 0.25
0 8828.62 4543414.50 -3.05 0 0.0021 0.61
而且你没有使用任何外部库。下面的代码会把数据读入一个包含字符串的 list
,同时会跳过那些不需要的行。你可以把这些行传递给你选择的任何其他函数。我这里用 print
只是为了演示一下。注意:第五列的索引是 '4',因为 list
的索引是从零开始的。
$ cat data.py
#!/usr/bin/env python
print "1. Delete the rows which have '0' as a value on 5th column:"
def zero_in_fifth(row):
return row.split()[4] == '0'
required_rows = [row for row in open('./data.txt') if not zero_in_fifth(row)]
print ''.join(required_rows)
print '2. Choose the range (i.e. remove the rows which have values between -50 and 30 on 5th column):'
def should_ignore(row):
return -50 <= float(row.split()[4]) <= 30
required_rows = [row for row in open('./data.txt') if not should_ignore(row)]
print ''.join(required_rows)
当你运行这段代码时,你会得到:
$ python data.py
1. Delete the rows which have '0' as a value on 5th column:
0 4028.44 4544434.50 -6.76 -117.00 0.0002 0.12
0 7028.56 4523434.50 -4.95 -137.00 0.0005 0.25
0 4028.44 4544434.50 -6.76 -107.00 0.0002 0.12
0 4028.50 3455014.50 -5.86 -11.00 0.0003 0.39
0 7028.56 4523434.50 -4.95 -127.00 0.0005 0.25
2. Choose the range (i.e. remove the rows which have values between -50 and 30 on 5th column):
0 4028.44 4544434.50 -6.76 -117.00 0.0002 0.12
0 7028.56 4523434.50 -4.95 -137.00 0.0005 0.25
0 4028.44 4544434.50 -6.76 -107.00 0.0002 0.12
0 7028.56 4523434.50 -4.95 -127.00 0.0005 0.25
2
你可以用numpy这个工具来快速完成这个任务:
data="""
0 4028.44 4544434.50 -6.76 -117.00 0.0002 0.12
0 4028.50 3455014.50 -5.86 0 0.0003 0.39
0 7028.56 4523434.50 -4.95 -137.00 0.0005 0.25
0 8828.62 4543414.50 -3.05 0 0.0021 0.61
0 4028.44 4544434.50 -6.76 -107.00 0.0002 0.12
0 4028.50 3455014.50 -5.86 -11.00 0.0003 0.39
0 7028.56 4523434.50 -4.95 -127.00 0.0005 0.25
0 8828.62 4543414.50 -3.05 0 0.0021 0.61
"""
from StringIO import StringIO
import numpy as np
d = np.loadtxt(StringIO(data)) # load the text in to a 2d numpy array
print d[d[:,4]!=0] # choose column 5 != 0
print d[(d[:,4]>=50)|(d[:,4]<=-30)] # choose column 5 >=50 or <=-30
4
goodrows = [row for row in data if row.split()[4] != '0']
或者
goodrows = [row for row in data if not (-50 <= float(row.split()[4]) <= 30)]
补充:
如果你的数据实际上是在一个NumPy数组里,虽然你的帖子没有直接说,但你的评论似乎暗示了这一点:
goodrows = [row for row in data if row[4] != 0]
或者
goodrows = [row for row in data if not (-50 <= row[4] <= 30)]
应该可以工作。不过,确实有NumPy内部的方法可以做到这一点。