2017-01-03 70 views
0

冷凝CSV文件较大所以CSV文件,我用外表那样工作:排序/按多列

Date Time,   SegmentID, indicatorvalue 
2016-12-01T00:00:00Z 147649  1 
2016-12-01T00:01:00Z 147649  0 
2016-12-01T00:02:00Z 147649  1 
...     ...   ... 
2016-12-01T00:23:00Z 2938733  0 

等。

我想要的是将其缩小到所有细分的列表中,然后该细分的多少条目具有指标值的百分比(按AM/IP/PM/OP )

如:

segmentID, Time Period, Percentage 
147649  AM   78 
147649  IP   100 
147649  PM   60 
147649  OP   30 
243546  AM   79 
243546  IP   98 
...   ...   ... 

我的尝试是建立一个for循环,使每个段将保持运行总指标百分比为一天的4倍,那么一旦它有检测到它已更改为新的segmentID,它会将这些值附加到字符串。

问题是,segmentIDs是无序的,导致同一个segmentID有多个条目。我试着按SegmentID排序文件,但文件太大了。有关替代方法的任何建议?

编辑: 有人谁删除了自己的评论贴,我应该用熊猫,所以经过一些调查,我的代码是目前:

import numpy as np 
import pandas as pd 

df=pd.read_csv("data.csv",sep=",",index_col="Segment ID",usecols=["Segment ID","Date Time","indicatorvalue"]) 
df['Date Time'] = ['AM' if '06' <= x[11:13] < '10' 
    else 'IP' if '10' <= x[11:13] < '16' 
    else 'PM' if '16' <= x[11:13] < '19' 
    else 'OP' if '19' <= x[11:13] or x[11:13] < '06' 
    else 'Error' for x in df['Date Time']] 

现在我只需要找出如何与凝结行'Date Time'和'SegmentID'的重复条目,同时平均他们的'指标值'。

+0

质量如此之大? –

+0

约3.5GB,不知道有多少行,但以百万计 –

+0

有多少内存可用,以及预计有多少段? –

回答

0

我设法制定出一个解决方案大熊猫。我使用的代码是:

import pandas as pd 

df=pd.read_csv("data.csv",sep=",",usecols=["Segment ID","Date Time","indicator value"]) 

df['Date Time'] = ['AM' if '06' <= x[11:13] < '10' 
    else 'IP' if '10' <= x[11:13] < '16' 
    else 'PM' if '16' <= x[11:13] < '19' 
    else 'OP' if '19' <= x[11:13] or x[11:13] < '06' 
    else 'Error' for x in df['Date Time']] 

grouped = df.groupby(['Segment ID','Date Time']).mean() 

grouped.to_csv('output.csv', sep =',') 

我不能推荐熊猫足够。

0

我假设输入文件的结构是每分钟一行,给出了开始时间,段ID和指标的值。

如果段的编号与可用内存兼容,我只需一次在线读取输入文件,然后将分钟添加到每个段的8个计数器,即每个时间段和指标值。这意味着初始文件只读取一次,而不是排序,唯一关键的数量是段的数量 - 如果它变得太高,我会使用sqlite3或dbm数据库而不是字典。

根据您当前的例子(与为一个CSV),代码可能是:

class Segment: 
    labels = ['AM', 'IP', 'PM', 'OP'] 
    def __init__(self, segid): 
     self.id = segid 
     self.values = [ [ 0, 0 ] for i in range(4) ] 
    def add(self, hour, indic): 
     ix = 3 
     if hour >= 6 and hour < 10: ix=0 
     elif hour >= 10 and hour < 16: ix=1 
     elif hour >= 16 and hour < 19: ix = 2 
     self.values[ix][indic] += 1 
    def percent(self, ix): 
     try: 
      return int(.5 + (100 * self.values[ix][1]/
       (self.values[ix][0] + self.values[ix][1]))) 
     except ZeroDivisionError: 
      return 0 

dummy = next(fd) 
splitter = re.compile(' +') 
segments = dict() 
for line in fd: # read and store 
    d, seg, indic = splitter.split(line.strip()) # could be replaced with a csv reader 
    hour = int(d[11:13]) 
    if not seg in segments: 
     segments[seg] = Segment(seg) 
    segments[seg].add(hour, int(indic)) 
for seg in sorted(segments.keys()): # output the stats 
    for ix in range(4): 
     print(seg, Segment.labels[ix], segments[seg].percent(ix)) 

上面的代码缺少错误检查或特殊条件