白手起家学习数据科学 ——处理数据之“数据清洗与再处理篇”(七)

数据清理与再处理(Cleaning and Munging)

真实世界的数据是脏的,在你使用数据之前,你不得不对数据做一些工作。例如,在”获取数据”章节中,在我们使用它们的时候,我们需要把字符串转换成floats或者ints:

closing_price = float(row[2])

解析数据可能减少错误,通过创建一个包裹csv.reader的函数来做这个。我们会给出一个解析器的清单,每个解析器说明怎样解析列中的一个,我们会使用None表示”对这个列不做任何操作”:

def parse_row(input_row, parsers):
    """given a list of parsers (some of which may be None)
    apply the appropriate one to each element of the input_row"""

    return [parser(value) if parser is not None else value
    for value, parser in zip(input_row, parsers)]

def parse_rows_with(reader, parsers):
    """wrap a reader to apply the parsers to each of its rows"""
    for row in reader:
        yield parse_row(row, parsers)

要是坏的数据怎么办?一个”float”值不是真的代表一个数字?我们通常会得到None而不是摧毁我们的程序,我们能利用helper函数来做这个:

def try_or_none(f):
    """wraps f to return None if f raises an exception
    assumes f takes only one input"""
    def f_or_none(x):
        try: return f(x)
        except: return None
    return f_or_none

然后我们能利用try_or_none函数重写parse_row函数:

def parse_row(input_row, parsers):
    return [try_or_none(parser)(value) if parser is not None else value
            for value, parser in zip(input_row, parsers)]

例如,如果我们有一个逗号分隔的股票数据,且其中有坏的数据:

这里写图片描述

现在我们读数据并解析:

import dateutil.parser
data = []

with open("comma_delimited_stock_prices.csv", "rb") as f:
    reader = csv.reader(f)
    for line in parse_rows_with(reader, [dateutil.parser.parse, None, float]):
        data.append(line)

做完上面之后,我们需要检查具有None的行:

for row in data:
    if any(x is None for x in row):
        print row

然后对于这些None行,决定我们想要对他们做什么。(一般来讲,有3个选项:(1)消除他们;(2)返回到数据源中,试着修改坏/丢失的数据;(3)什么也不做,期求后面的操作能通过)

我们能为csv.DictReader创建类似的helpers,这种情况,你可能想要提供具有字段名的key作为字典,字典的value为解析器。例如:

def try_parse_field(field_name, value, parser_dict):
    """try to parse value using the appropriate function from parser_dict"""
    parser = parser_dict.get(field_name) # None if no such entry
    if parser is not None:
        return try_or_none(parser)(value)
    else:
        return value

def parse_dict(input_dict, parser_dict):
    return { field_name : try_parse_field(field_name, value, parser_dict)
                for field_name, value in input_dict.iteritems() }

下一步就是检测离群值(outliers),例如,你注意到在股票数据中”3014年”了么,那个没有给我们任何错误,但是很明显是错误的,如果你不获取它,你会得到错误的结论。真实的世界中数据集有很多丢失小数、很多0、排版错误以及无数其他问题需要我们处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值