Python - 读取csv并按列分组数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python - 读取csv并按列分组数据相关的知识,希望对你有一定的参考价值。
我正在使用带有3列的csv文件,如下所示:
timeStamp, value, label
15:22:57, 849, CPU pid=26298:percent
15:22:57, 461000, JMX MB
15:22:58, 28683, Disks I/O
15:22:58, 3369078, Memory pid=26298:unit=mb:resident
15:22:58, 0, JMX 31690:gc-time
15:22:58, 0, CPU pid=26298:percent
15:22:58, 503000, JMX MB
'label'列包含不同的值(总共5个),包括空格,冒号和其他特殊字符。
我想要实现的是针对每个度量标准绘制时间(在同一个绘图上或在单独的绘图上)。我可以用Matplotlib做到这一点,但我首先需要根据'标签'对[timeStamps, value]
对进行分组。
我查看了csv.DictReader
以获得标签和itertools.groupby
按“标签”分组,但我正在努力以适当的'pythonic'方式做到这一点。
有什么建议吗?
谢谢
你不需要groupby
;你想用collections.defaultdict
来收集由标签键入的一系列[timestamp, value]
对:
from collections import defaultdict
import csv
per_label = defaultdict(list)
with open(inputfilename, 'rb') as inputfile:
reader = csv.reader(inputfile)
next(reader, None) # skip the header row
for timestamp, value, label in reader:
per_label[label.strip()].append([timestamp.strip(), float(value)])
现在per_label
是一个字典,标签为键,[timestamp, value]
列表作为值;我已经剥离了空白(你的输入样本有很多额外的空格)并将value
列变成了浮点数。
对于(有限的)输入样本,导致:
{'CPU pid=26298:percent': [['15:22:57', 849.0], ['15:22:58', 0.0]],
'Disks I/O': [['15:22:58', 28683.0]],
'JMX 31690:gc-time': [['15:22:58', 0.0]],
'JMX MB': [['15:22:57', 461000.0], ['15:22:58', 503000.0]],
'Memory pid=26298:unit=mb:resident': [['15:22:58', 3369078.0]]}
您可以尝试pandas,它提供了一个很好的结构来处理数据。
阅读csv到DataFrame
In [123]: import pandas as pd
In [124]: df = pd.read_csv('test.csv', skipinitialspace=True)
In [125]: df
Out[125]:
timeStamp value label
0 15:22:57 849 CPU pid=26298:percent
1 15:22:57 461000 JMX MB
2 15:22:58 28683 Disks I/O
3 15:22:58 3369078 Memory pid=26298:unit=mb:resident
4 15:22:58 0 JMX 31690:gc-time
5 15:22:58 0 CPU pid=26298:percent
6 15:22:58 503000 JMX MB
通过DataFrame
对label
进行分组
In [154]: g = df.groupby('label')
现在你可以得到你想要的东西
In [155]: g.get_group('JMX MB')
Out[155]:
timeStamp value label
1 15:22:57 461000 JMX MB
6 15:22:58 503000 JMX MB
你可以使用numpy.loadtxt
:
import numpy as np
result = np.loadtxt('MYFILE', usecols=(0, 1, 2),
dtype=[('time', 'S8'), ('values', np.uint), ('label', 'S33')],
delimiter=', ')
这会将表加载到结构化数组中,其中时间保存为8个字符的字符串('S8'),值为无符号整数,标签为最多33个字符的字符串('S33',您可能需要调整这个尺寸)。然后,您可以按类型索引值:
>>> print result['values']
[ 849 461000 28683 3369078 0 0 503000]
并根据标签过滤,如果您需要:
>>> print result['values'][result['label'] == 'JMX MB']
[461000 503000]
要将时间从字符串转换为浮点数,您可以使用pylab
的日期datestr2num
并将其作为转换器提供给loadtxt
:
import pylab
result = np.loadtxt('MYFILE', usecols=(0, 1, 2),
dtype=[('time', np.float), ('values', np.uint), ('label', 'S33')],
delimiter=', ', converters={0: pylab.datestr2num})
以上是关于Python - 读取csv并按列分组数据的主要内容,如果未能解决你的问题,请参考以下文章