2011-06-06 45 views
2

首先,让我们一起分析一下,如果我的描述被完全推迟了,仍然可以在大部分时间里学习。解析大型文本文件并捕获多级数据的Python

我有几个大的文本文件(.txt)(约600,000行)的综合医院信息,我用python解析。我一直在使用默认的字典(python2.7)来获得计数和子计数,它们是pt的一个深度。诊断。例如,如果希望赶上心脏病发作,然后区分基于类型(伪):

if 'heart attack' in line[65:69]: 
    defaultdict['heart attack'] +=1 
    if [65:69] == 'worst kind': 
     defaultdict['worst'] += 1 
    else: 
     defaultdict['not worst'] +=1 

这样,我赶上心脏发作和是否他们所关心的具体的一个。这一切都很好。但是,现在我也想收集患者年龄(编码范围报告),性别(男性,女性,U)和种族等信息(来自同一行)。我意识到我的技术是不太适合这一点 - 它似乎以快速增长的复杂性。所以,在我深入挖掘之前 - 还有另一种方法可以解决这个问题吗?

最终,我打算将所有这些文件都放到实际的数据库中,但这基本上是最后一条信息。我需要为当前的项目,所以我很舒服,只是倾销到Excel和现在的图形。

感谢您的任何建议!

编辑:样品管线就像 -

02032011JuniorHospital  932220320M09A228393 
03092011MassGeneralHospitals 923392818F09B228182 

因此,所有线将固定长度,其中行:(?字典)[0 8]总是日期等有一个单独的文件,它解释这些数字的含义 - 因此诊断将会像410.22那样,年龄将在0 = 0-1岁,1 = 2-3岁等等范围内......

目标:对于每个诊断我想,也想知道是特别诊断了一个子类型(没有问题,以上代码得到这么多),与诊断有关的各种年龄(即每个年龄段有多少)有什么关系。我目前有这个输出到excel文件(csv),所以我想要各种多列,我可以绘制我需要的。

再次,我可以弄清楚如何做到这一切,只是创建一些额外的默认字典 - 它似乎应该有一个更简单的方法将它们组合成一个主要对象!

+0

如果您给我们一个关于文件格式的提示,我们可能会给你一个提示如何解析它。 (几行示例数据会很棒。) – 2011-06-06 22:04:46

+0

这完全取决于您想要的输入和输出格式。但是一个成熟的DB-ORM库可能会帮你解决。 – Santa 2011-06-06 22:07:31

+0

1.这是一个简单的.txt文件,固定行(所有行相同长度)2.我输出到.csv(使用excel)并使用Dictwriter。 – chris 2011-06-06 23:53:09

回答

5

您可以概括分层计数的概念以获得更易于修改的更清晰的代码。分级计数器类的基本示例是

class HierarchicCounter(object): 
    def __init__(self, key, hierarchy): 
     self.key = key 
     self.hierarchy = hierarchy 
     self.counts = defaultdict(int) 
     self.subcounters = defaultdict(self._create_subcounters) 

    def _create_subcounters(self): 
     return {key: HierarchicCounter(key, hierarchy) 
       for key, hierarchy in self.hierarchy.iteritems()} 

    def count(self, line): 
     key = self.key(line) 
     if key is None: 
      return 
     self.counts[key] += 1 
     for subcounter in self.subcounters[key].itervalues(): 
      subcounter.count(line) 

该类的构造函数接受两个参数。 key参数是“关键函数”,它告诉计数器它应该计算的值。如果一条线被输入到计数器中,它将使用键功能并增加与检索到的键相对应的计数。 hierarchy参数是将所需子计数器的关键函数映射到其各自层次的字典。

实例:

def diagnosis_major(line): 
    return line[0:3] 

def diagnosis_minor(line): 
    return line[3:5] 

def age(line): 
    return int(line[5:7]) 

def sex(line): 
    return line[7] 

counter = HierarchicCounter(
    diagnosis_major, {diagnosis_minor: {sex: {}}, age: {}}) 

这产生了一些简单的键功能从线提取不同的字段。在您的应用程序中,关键功能可能会变得更加复杂。您也可以在这里过滤出密钥 - 如果一个关键函数返回None,计数器将忽略该行。最后两行做出HierarchicCounter实例有以下数层次:

diagnosis_major 
|-- diagnosis_minor 
| \-- sex 
\-- age 

所以计数器计数每个主要诊断的病例数。对于每个主要诊断,它都计算与这一主要诊断相对应的轻微诊断和年龄。对于每次轻微的诊断,都要对每个主要诊断进行性别计数。

当然这个例子并不完整。您需要添加一些代码,以某种格式实际输出计数器层次结构中收集的计数 - 这只是为了让您了解如何以更一般的方式提取这些数据。

+0

你先生,已经超越了。这是我想象中的那种类型,尽管它超出了我的思维范围。谢谢! – chris 2011-06-07 14:12:12

0

这听起来对我来说,你是在同样的情况我是当我奋力把从他们的文本和提取数据不知道正则表达式的存在(见模块重新)

在对你想做什么进行精确测试,我们会帮助你做你想做的事。就个人而言,它将与正则表达式的力量。

+0

对不起 - 这是一个固定长度的格式,所以我可以很容易地做线[66:67]并检查这样的值;认为这将比正则表达式更容易(纠正我,如果错误)。将更新我的原始文章了一下。 – chris 2011-06-06 23:57:15

2

如果你把每一行放入一个元组中,你可以对该元组中的任何字段或字段进行排序。提供比较元素的自定义比较器功能。例如你的比较函数将在字段1和字段3上进行排序。如果字段1是疾病,字段3是年龄,它会对年龄进行排序,并且在每个年龄段内您都会有一个排序的疾病列表。相当容易适应,例如:疾病和年龄,并在每次疾病后分割列表。

http://wiki.python.org/moin/HowTo/Sorting/

话虽这么说,但没有SQL或电子表格,你可能看多类型的字典。