【问题标题】:Python remove negative number entries/rows from csvPython从csv中删除负数条目/行
【发布时间】:2012-05-28 03:19:52
【问题描述】:

我有一个不断增长的 csv 文件,看起来像:

143100, 2012-05-21 09:52:54.165852
125820, 2012-05-21 09:53:54.666780
109260, 2012-05-21 09:54:55.144712
116340, 2012-05-21 09:55:55.642197
125640, 2012-05-21 09:56:56.094999
122820, 2012-05-21 09:57:56.546567
124770, 2012-05-21 09:58:57.046050
103830, 2012-05-21 09:59:57.497299
114120, 2012-05-21 10:00:58.000978
-31549410, 2012-05-21 10:01:58.063470
90390, 2012-05-21 10:02:58.108794
81690, 2012-05-21 10:03:58.161329
80940, 2012-05-21 10:04:58.227664
102180, 2012-05-21 10:05:58.289882
99750, 2012-05-21 10:06:58.322063
87000, 2012-05-21 10:07:58.391256
92160, 2012-05-21 10:08:58.442438
80130, 2012-05-21 10:09:58.506494

当生成文件的服务出现 API 连接失败时,会出现负数。我已经在使用 matplotlib 来绘制数据图表,但是人工负数极大地扭曲了图表。我想找到所有负面条目并删除相应的行。在任何时候,负数都不能真正代表任何真实数据。

在 Bash 中,我会执行以下操作:

awk '{print $1}' original.csv | sed '/-/d' > new.csv

但这很麻烦,而且往往很慢,如果我能提供帮助,我真的不想在我的 python 图形脚本中嵌入 bash 命令。

谁能指出我正确的方向?

编辑:

这是我用来读取/绘制数据的代码:

import matplotlib
matplotlib.use('Agg')                                          
from matplotlib.mlab import csv2rec                           
import matplotlib.pyplot as plt                               
import matplotlib.dates as mdates                              
from pylab import *                                         

output_image_name='tpm.png'                   

data = csv2rec('counter.log', names=['packets', 'time'])   
rcParams['figure.figsize'] = 10, 5                              
rcParams['font.size'] = 8                                       

fig = plt.figure()                                              

plt.plot(data['packets'], data['time'])                      

ax = fig.add_subplot(111)                                       
ax.plot(data['time'], data['tweets'])                         
hours = mdates.HourLocator()                                    
fmt = mdates.DateFormatter('%D - %H:%M')                       
ax.xaxis.set_major_locator(hours)                               
ax.xaxis.set_major_formatter(fmt)                               

ax.grid()                                                

plt.ylabel("packets")                                         
plt.title("Packet Log: Packets Per Minute")         

fig.autofmt_xdate(bottom=0.2, rotation=90, ha='left')         

plt.savefig(output_image_name)

【问题讨论】:

  • 你的python脚本是如何读取数据的?它可以像在循环中跳过以 - 开头的行一样简单,但您不显示任何代码。
  • 那个awk '{print $1}'是不必要的,你可以用sed '/-/d' original.csv > new.csv
  • @wooble 我已添加绘图代码以响应您的评论

标签: python linux csv awk matplotlib


【解决方案1】:

Python 习惯用法是使用生成器表达式来过滤行:

sys.stdout.writelines(line for line in sys.stdin if not line.startswith('-'))

或者在处理上下文中:

filtered = (line for line in sys.stdin if not line.startswith('-'))
for line in filtered:
    # ...

【讨论】:

  • 这不是writelines 参数中缺少另一对圆括号 () 以使列表理解创建生成器吗?
  • @Jan:不,这不是列表推导,而是生成器表达式。如果它是函数的唯一参数,则这对括号是不必要的。
  • @Niklas B. 就其本身而言,它可能并不比 sed 快,但由于他已经在 Python 中进行迭代,因此在那里进行过滤也是有意义的。
  • 我在我的绘图脚本中使用 csv2rec:data = csv2rec(counter.log, names=['packets', 'time']) 我是否推断它看起来像:过滤= (line for line in 'tpm_counter.log' if not line.startswith('-')) for line in filters: data = csv2rec(line, names=['packets', 'time'])
  • @secumind:如果您在谈论 matplotlib,那么不, csv2rec 采用文件名或类似文件的对象,而不是字符串。您可以像在from cStringIO import StringIO; f = StringIO(''.join(filtered)); data = csv2rec(f, ...) 中那样使用stringio,但这需要您将整个文件加载到内存中。最简单的解决方案是使用 sed 或 Python 预先实际预处理文件并将其写入新位置(可能在 RAM 磁盘上)
【解决方案2】:

我不会重写文件,而是在读取时过滤数据,即在绘图之前。

【讨论】:

  • 这将是一个很好的方法,尤其是因为它可以让您掌握潜在的重要信息。无需从文件中删除它,这样您就可以正确地绘制它。
  • @Jan-Philip 我已经添加了我的绘图代码,我同意这将是理想的方式,我只是不确定何时使用 csv2rec 来做到这一点。
【解决方案3】:

此程序会打开您的 csv 文件,删除以负整数开头的行,并将其保存到不同的文件中。如果你愿意,你可以在同一个文件上稍作修改覆盖它。

with open('data.csv', 'r') as f:
    with open('data2.csv', 'w') as g:
        for row in f:
            if row[0] != '-':
                g.write(row)

【讨论】:

  • 这对于 OP 的目的来说似乎是不必要的复杂。你为什么要把行分开,最后又把它们连在一起?
  • -1 用于不使用csv 模块,用于将整个文件读入内存,以及用于修改您正在迭代的列表(这是一个错误)。另外,with 声明已经发布了一段时间,您不要使用它。
  • @JoelCornett,已修复。那是愚蠢的。我在找负整数,我可以找一个减号。
  • @JoelCornett,非常感谢。我不知道你可以遍历一个文件,或者任何关于withwrite 的东西。从这个问题中得到了很多东西:-)
  • 你也可以使用with open('data.csv', 'r') as f, open('data2.csv', 'w') as g:来避免嵌套
猜你喜欢
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-12
相关资源
最近更新 更多