PythonPython

Python 数据处理(二)

2021-01-06  本文已影响0人  名本无名

前言

前面我们说到了数据的读取,既然数据都已经读取进来了,下面我们进入正题,聊聊如何进行数据处理。

一般,我们遇到的数据基本上都是矩阵格式的,每行每列都有特定的含义。例如,学生成绩

姓名 阅读成绩 数学成绩 写作成绩
female 72 72 74
female 69 90 88
female 90 95 93
male 47 57 44
male 76 78 75

而对一些结构性的数据,比如 json 数据,读取后就变成了字典类型的数据结构了。可以对字典遍历修改调整。

xml 格式的数据,可以用 xmllxml 等模块进行操作。

或者一些看起来不是很规则的数据,我们可以将其转换为自己熟悉的数据格式,然后对其进行操作。

示例

不规则文件读取

例如,对于 KEGG 的化合物 C01290 的部分信息,我们想要获取其 entryname 列表, enzyme 列表,以及外部链接 ID 列表

ENTRY       C01290                      Compound
NAME        Lactosylceramide;
            beta-D-Galactosyl-(1->4)-beta-D-glucosyl-(1<->1)-ceramide;
            beta-D-Galactosyl-1,4-beta-D-glucosylceramide;
            Gal-beta1->4Glc-beta1->1'Cer;
            LacCer;
            Lactosyl-N-acylsphingosine;
            D-Galactosyl-1,4-beta-D-glucosylceramide
FORMULA     C31H56NO13R
REMARK      Same as: G00092
COMMENT     Generic compound in reaction hierarchy
REACTION    R03354 R03355 R03486 R03488 R03489 R03490 R03491 R03492 
            R03618 R04493
PATHWAY     map00600  Sphingolipid metabolism
            map01100  Metabolic pathways
MODULE      M00066  Lactosylceramide biosynthesis
ENZYME      2.4.1.92        2.4.1.206       2.4.1.228       2.4.1.274       
            2.4.99.1        2.4.99.9        3.2.1.18        3.2.1.22        
            3.2.1.23        3.2.1.47        3.2.1.52
BRITE       Compounds with biological roles [BR:br08001]
             Lipids
              Glycolipids
               Glycosphingolipids
                C01290  Lactosylceramide
DBLINKS     PubChem: 4509
            ChEBI: 17950
            LIPIDMAPS: LMSP0501AB00
            LipidBank: GSG1147

对于这种数据,没有直接能用的读取方式,那如何获取我们想要的信息呢?

其实,我们可以将第一列 ENTRY, NAME, ..., DBLINKS 看作是字典的键,后面的信息就是其所对应的值。构造一个字典来存储我们想要的数据信息。

话虽这么说,是不是还是有点无从下手呢?

那么在读取数据之前,我们先观察一下这个数据的规律,仔细瞧瞧。。。

虽然每行数据之间的分隔并不是统一的像 \t, , 这个的固定分隔符,但是呢,键都是在每行的开头,值的位置都是在每行的统一的固定位置,这样我们就能分隔出键和值了。

而键所对应的值是多行时,除了第一行是有键的,后面的行前面都是空白字符串,这样一来是不是有头绪啦。

好,那我们开始操作一下吧

1. 先获取数据

import requests

link = 'http://rest.kegg.jp/get/C01290'
res = requests.get(link)
text = res.text

在这,我们使用 requests 模块爬取 KEGG API 接口的数据。其实呢,你也可以直接在浏览器中输入 http://rest.kegg.jp/get/C01290 网址,并下载该数据。

如果是下载到本地的数据 C01290.txt,那么我们可以

with open('C01290.txt', 'r') as f:
    text = f.read()

2. 获取分隔点

>>> line =  text.split('\n')[0]
>>> line
# 'ENTRY       C01290                      Compound'
>>> line.index('C')
# 12

从结果可以看出,前 12 个字符包含的是键,后面的字符包含的是值。

>>> line =  text.split('\n')[2]
>>> line[:12]
# '            '

而在第 3 行,前 12 个字符都是空字符

这样,我们就可以对前 12 个字符中存在非空字符的行,作为键和第一个值。

而对前 12 个字符都是空字符的行,作为前一个键的补充值,加入列表中。

3. 读取并存储为字典

data = {}
for line in text.split('\n'):
    prefix = line[:12].strip()
    if prefix:
        key = prefix
    value = line[12:].strip()
    if key == 'ENTRY':
        data[key] = value.split()[0]
    elif key == 'NAME':
        data[key] = data.get(key, []) + [value.strip(';')]
    elif key == 'ENZYME':
        data[key] = data.get(key, []) + value.split()
    elif key == 'DBLINKS':
        data[key] = data.get(key, {})
        k, v = value.split(': ')
        data[key][k] = v

看看最后获取到的信息

{
    'ENTRY': 'C01290',
    'NAME': [
        'Lactosylceramide',
        'beta-D-Galactosyl-(1->4)-beta-D-glucosyl-(1<->1)-ceramide',
        'beta-D-Galactosyl-1,4-beta-D-glucosylceramide',
        "Gal-beta1->4Glc-beta1->1'Cer",
        'LacCer',
        'Lactosyl-N-acylsphingosine',
        'D-Galactosyl-1,4-beta-D-glucosylceramide'
     ],
    'ENZYME': [
        '2.4.1.92',
        '2.4.1.206',
        '2.4.1.228',
        '2.4.1.274',
        '2.4.99.1',
        '2.4.99.9',
        '3.2.1.18',
        '3.2.1.22',
        '3.2.1.23',
        '3.2.1.47',
        '3.2.1.52'
      ],
     'DBLINKS': {
        'PubChem': '4509',
        'ChEBI': '17950',
        'LIPIDMAPS': 'LMSP0501AB00',
        'LipidBank': 'GSG1147'
     }
}

OK,提取成功,大功告成

总结

对于不太规则的数据,我们可以先看看数据的一些潜在的规律。然后,根据规律对每一行遍历提取所需的字符串,并存储为字典。

看起来很复杂的东西,还是有规律可循的,要善于发现数据中潜在的规律以及可行的提取方式。当然,还是需要多加练习,孰能生巧。

对于这类数据的处理,我们也不再举例说明了,大家消化一下。

上一篇 下一篇

猜你喜欢

热点阅读