Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python—读取csv并按列分组数据_Python_Csv - Fatal编程技术网

Python—读取csv并按列分组数据

Python—读取csv并按列分组数据,python,csv,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:pe

我正在处理一个包含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
标签
列包含不同的值(比如总共5个),其中包括空格、冒号和其他特殊字符

我试图实现的是根据每个指标绘制时间图(在同一个图上或在不同的图上)。我可以使用
matplotlib
,但首先需要根据“标签”对
[时间戳,值]
对进行分组

我查看了
csv.DictReader
以获得标签,并将
itertools.groupby
以“标签”进行分组,但我正在努力以一种正确的“pythonic”方式完成这项工作

有什么建议吗?

您可以使用:

这将把表加载到一个结构化数组中,其中时间保存为8个字符的字符串(“S8”),值保存为无符号整数,标签保存为最多33个字符的字符串(“S33”,您可能需要调整此大小)。然后,可以按类型为值编制索引:

>>> print result['values']
[    849  461000   28683 3369078       0       0  503000]
并根据标签进行过滤,如果需要:

>>> print result['values'][result['label'] == 'JMX MB']
[461000 503000]
要将时间从字符串转换为浮点数,可以使用
pylab
的date
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})

您不需要
groupby
;您要使用收集由标签键入的一系列
[时间戳,值]
对:

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
是一个字典,标签作为键,而
[时间戳,值]
对作为值;我已经去掉了空白(您的输入示例有很多额外的空白),并将
列变成了浮点数

对于您的(有限的)输入样本,其结果为:

{'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]]}
您可以尝试提供一个很好的结构来处理数据

将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
按标签对数据帧进行分组

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

您的示例的预期输出是什么?好吧,鉴于我的输入样本都是混合的,我可能需要为每个[label]分离[times]和[values]。我最初的方法是读取标签,然后读取每一行,并根据标签存储每一对[time,value]。但这似乎是一个非常低效的方法,这就是为什么我想研究字典和迭代器。这就像一个魅力!谢谢,我的文件可能会超过3列,但我想我可以处理这个问题。我假设我只需要添加:对于读卡器中的时间戳、值、标签:@ArgyriosTzakas:您也可以只对读卡器中的行执行
,然后使用索引、
行[1]
行[5]
,等等。
csv.DictReader()
将用dict替换列表,这样您就可以执行
行['timestamp']
,而不是
行[0]
;如果您切换到
reader.DictReader
,请省去
next()
调用。谢谢Martijn。在一个相关的话题上,有没有一种聪明的方法可以根据关键字拆分我的字典,而不必硬编码?例如,我可以这样做l1,l2,l3=per_label.values(),但如果我有3个以上的键怎么办?@ArgyriosTzakas:为什么需要解压这些值?通过解包为3个变量,您已经硬编码了变量名。只需在字典上循环:
用于输入每个标签:
用于每个标签中的值。值():
,等等,或者将所有值存储在一个列表中:
值列表=每个标签。值()
,然后在其他地方循环。非常有趣。我将研究熊猫,因为我将进行许多类似的数据操作。谢谢您可以添加如何将分组的CSV写入文件吗?不是很琐碎:
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