1.4 表和记录

诗人、哲学家Steve Martin曾说:

“Oeuf”就是egg,“chapeau”就是hat。好像所有的东西在法语中都跟在英语中的叫法不一样。

跟法语一样,数据库程序员的语言也跟我们的日常语言稍有不同。因为我们要谈到数据库,所以有必要学习一些专业术语。

被调查者文件中的每一行都表示一个被调查者。这行信息称为一条记录(record),组成记录的变量称为字段(field),若干记录的集合就组成了一个表(table)。

看一下survey.py中的代码,就会看到Record和Table这两个类的定义,前者是代表记录的对象,后者则是表示表的对象。

Record有两个子类,分别是Respondent和Pregnancy,两者分别是被调查者和怀孕的记录。目前这些类暂时还是空的,其中还没有用于初始化其属性的init方法。我们会用Table.MakeRecord方法将一行文本转换成一个Record对象。

Table也有两个子类Respondents和Pregnancies。这两个类的init方法设置了数据文件的默认名称和要创建的记录的类型。每个Table对象都有一个records属性,是一个Record对象的列表。

每个Table的GetFields方法返回一个指定记录字段的元组(tuple)列表,这些字段就是Record对象的属性。

例如,下面是Pregnancies.GetFields:

def GetFields(self): 
  return [ 
    ('caseid', 1, 12, int), 
    ('prglength', 275, 276, int), 
    ('outcome', 277, 277, int), 
    ('birthord', 278, 279, int), 
    ('finalwgt', 423, 440, float), 
   ]

第一个元组的意思从第1列到第12列是caseid字段,且类型为整数。每个元组包含如下信息。

  • field (字段名) 保存该字段的属性的名称。大部分情况下,我使用NSFG编码手册中的名称,全部用小写。
  • start (起始列) 该字段的起始列编号。例如,caseid的起始编号是1。可以在NSFG编码手册中查询这些编号:http://www.icpsr.umich.edu/nsfg6/
  • end(结束列) 该字段的结束列编号。例如,caseid的结束列编号是12。跟Python中不一样,这里的结束列也是该字段的一部分。
  • 转换函数 将字符串转换成其他类型的函数。可以用内置的函数,比如int和float,也可以使用用户自定义的函数。如果转换失败,属性的值就会是字符串'NA'。如果某个字段不需要转换,可以使用identity函数或是str函数。

从pregnancy记录中可以得到以下变量。

  • caseid 被调查者的整数ID。
  • prglength 怀孕周期,单位是周。
  • outcome 怀孕结果的整数代码。代码1表示活产。
  • birthord 正常出生的婴儿的顺序。例如,第一胎婴儿的编号是1。如果没有正常出生,该字段为空。
  • finalwgt 被调查者的统计权重。这是一个浮点值,表示这名被调查者所代表的人群在美国总人口中的比例。过采样人群的权重偏低。

如果你仔细阅读编码手册,就会发现这些变量大部分都经过了重编码(recode),也就是说这并不是调查所采集的原始数据,而是根据原始数据计算出来的。

例如,第一胎活婴的prglength在原始数据中有变量wksgest(妊娠周数)时就等于该变量的值,否则就会用mosgest * 4.33(妊娠月数乘以每个月的平均周数)估计出来。

重编码通常遵循数据一致性和准确性原则。除非有特别原因一定要使用原始数据,否则就应该直接使用重编码后的数据。

你可能还发现了Pregnancies有Recode方法,用来做一些其他的检查和重编码工作。

习题1-3

在这个练习中,我们会编写一个程序来看看Pregnancies表中的数据。

  1. 在survey.py和数据文件的目录中创建一个first.py文件,然后将下面的代码输入或复制到文件中:

    import survey 
    table = survey.Pregnancies() 
    table.ReadRecords() 
    print 'Number of pregnancies', 
    len(table.records)
    

    结果应该是13 593条怀孕记录。

  2. 编写一个循环遍历表(table),计算其中活婴的数量。查阅临床结果(outcome)的文档,确认你的结果跟文档中的总结一致。

  3. 修改这个循环,将活婴的记录分成两组:一组是第一胎出生;另一组是其他情况。再看一些出生顺序(birthord)的文档,看看你的结果跟文档中的结果是否一致。 在处理新的数据集时,这种检查对于发现数据中的错误和不一致性、检查程序中的错误以及检验对字段编码方式的理解是否正确等都是很有用的。
  4. 分别计算第一胎宝宝和其他宝宝的平均怀孕周期(单位是周)。两组之间有差异吗?差异有多大?

http://thinkstats.com/first.py可下载这个练习的答案。