python---数据清洗

2023-11-04

干净整洁的数据是后续进行研究和分析的基础。数据科学家们会花费大量的时间来清理数据集,毫不夸张地说,数据清洗会占据他们80%的工作时间,而真正用来分析数据的时间只占到20%左右。

所以,数据清洗到底是在清洗些什么?

通常来说,你所获取到的原始数据不能直接用来分析,因为它们会有各种各样的问题,如包含无效信息,列名不规范、格式不一致,存在重复值,缺失值,异常值等…

1、了解数据

拿到一个全新的数据集,我们需要先了解数据,看看它长什么样子。

常用的方法和属性如下:

方法 属性
.head() 查看前n行数据,默认值是5
.tail() 查看后n行数据,默认值是5
.shape 查看数据维数
.columns 查看所有列名
.info() 查看索引、数据类型和内存信息
.describe() 查看每列数据的基本统计值,包括计数值、均值、标准差、最小最大值、1/4、1/2、3/4分位数。
.value_counts() 查看Series对象的唯一值和计数值

2、清洗数据

了解数据集之后,我们就可以开始对数据集进行清洗了,前面提到通常要处理的问题有包含无效信息,列名不规范、格式不一致,存在重复值,缺失值,异常值等。

1、去除不需要的行、列

在分析一个数据集的时候,很多信息其实是用不到的,因此,需要去除不必要的行或列。这里以csv文件为例,在导入的时候就可以通过设置pd.read_csv()里面的参数来实现这个目的。

【header】默认header=0,即将文件中的0行作为列名和数据的开头,但有时候0行的数据是无关的,我们想跳过0行,让1行作为数据的开头,可以通过将header设置为1来实现。

【usecols】根据列的位置或名字,如[0,1,2]或[‘a’, ‘b’, ‘c’],选出特定的列。

【nrows】要导入的数据行数,在数据量很大、但只想导入其中一部分时使用。

导入数据,只选取前100行和特定几列。

subset_columns = ['Job #', 'Doc #', 'Borough', 'Initial Cost', 'Total Est. Fee']
df = pd.read_csv('文件路径', nrows=100, usecols=subset_columns)
df.head()
Out[15]: 
       Job #  Doc #   Borough Initial Cost Total Est. Fee
0  420291794      1    QUEENS     $2000.00        $100.00
1  420291801      1    QUEENS    $15000.00        $151.50
2  340644128      1  BROOKLYN    $44726.00        $234.00
3  421685439      1    QUEENS        $0.00        $243.00
4  421677974      2    QUEENS   $105000.00       $1275.60

再看一下将header设置为1的效果,但这里其实不需要这么做,因为0行数据是有用的。

df = pd.read_csv('文件路径', nrows=100, header=1)
df.head()
Out[15]: 
0  420291794      1    QUEENS     $2000.00        $100.00
1  420291801      1    QUEENS    $15000.00        $151.50
2  340644128      1  BROOKLYN    $44726.00        $234.00
3  421685439      1    QUEENS        $0.00        $243.00
4  421677974      2    QUEENS   $105000.00       $1275.60

如果在数据导入之后,还想删除某些行和列,可以用 .drop() 方法。

先创建一个列表list,把不需要的列名放进去,再调用.drop() 方法,参数axis为1时代表列,为0时代表行,参数inplace=True表示不创建新的对象,直接对原始对象进行修改。这里我们删除前两列。

to_drop = ['Job #', 'Doc #']
df.drop(to_drop, axis=1, inplace=True)
df.head()
Out[22]: 
    Borough Initial Cost Total Est. Fee
0    QUEENS     $2000.00        $100.00
1    QUEENS    $15000.00        $151.50
2  BROOKLYN    $44726.00        $234.00
3    QUEENS        $0.00        $243.00
4    QUEENS   $105000.00       $1275.60

2、重新命名列

当原始数据的列名不好理解,或者不够简洁时,可以用.rename()方法进行修改。这里我们把英文的列名改成中文,先创建一个字典,把要修改的列名定义好,然后调用rename()方法。

new_names = {'Borough': '区', 'Initial Cost': '初始成本', 'Total Est. Fee': '总附加费用'}
df.rename(columns=new_names, inplace=True)
df.head()
Out[23]: 
          区        初始成本     总附加费用
0    QUEENS    $2000.00   $100.00
1    QUEENS   $15000.00   $151.50
2  BROOKLYN   $44726.00   $234.00
3    QUEENS       $0.00   $243.00
4    QUEENS  $105000.00  $1275.60

3、重新设置索引

数据默认的索引是从0开始的有序整数,但如果想把某一列设置为新的索引,可以用.set_index()方法实现,在示例中我们把"区"这列设置为新索引。

df.set_index('区', inplace=True)
df.head()
Out[24]: 
                初始成本     总附加费用
                             
QUEENS      $2000.00   $100.00
QUEENS     $15000.00   $151.50
BROOKLYN   $44726.00   $234.00
QUEENS         $0.00   $243.00
QUEENS    $105000.00  $1275.60

4、用字符串操作规范列

字符串str操作是非常实用的,因为列中总是会包含不必要的字符,常用的方法如下:

方法 属性
str.lower() 把大写转换成小写
str.upper() 把小写转换成大写
str.capitalize() 设置首字母大写
str.replace() 替换特定的字符
str.strip() 去除字符串中的头尾空格、以及\n \t
tr.split(‘x’) 使用字符串中的’x’字符作为分隔符,将字符串分隔成列表
str.get() 选取列表中某个位置的值
str.contains() 判断是否存在某个字符,返回的是布尔值
str.find() 检测字符串中是否包含子字符串str,如果是,则返回该子字符串开始位置的索引值

5、删除重复数据

重复数据会消耗不必要的内存,在处理数据时执行不必要的计算,还会使分析结果出现偏差。因此,我们有必要学习如何删除重复数据。

一个简单的例子代码:

删除缺失值:

import numpy as np
import pandas as pd

def create_csv():
    """测试删除缺失值的数据准备"""
    # 创建一个带有缺失值的数据
    df = pd.DataFrame(np.arange(12).reshape(3,4),
                      index=['user1','user2','user3'],
                      columns=['views','likes','count','price'])

    # 第2行的第三列为缺失值
    df.iloc[1,2] = np.nan
    # print(df)
    # 将数据存储到csv文件中
    df.to_csv('doc/data-clean.csv')

def drop_null_data():
    # 读取数据
    df = pd.read_csv('doc/data-clean.csv')
    df1 = df.dropna() # 默认删除带有缺失值的那一行
    # df1 = df.dropna(axis=1) # 删除带有缺失值的那一列,不建议使用
    print(df1)

if __name__ == '__main__':
    drop_null_data()

这里的数据是我们自己建立的,数据量特别小,当我们遇到大量数据的时候,我们通常需要先执行上面的第一步。

6、填充缺失值

数据集中经常会存在缺失值,学会正确处理它们很重要,因为在计算的时候,有些无法处理缺失值,有些则在默认情况下跳过缺失值。而且,了解缺失的数据,并思考用什么值来填充它们,对做出无偏的数据分析至关重要。
填充缺失值:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(12).reshape(4,3),
                  index=['user1', 'user2', 'user3', 'user4'],
                  columns=['count', 'views', 'price'])

df.price.iloc[0] = np.nan
df.price.iloc[2] = 5
print('元数据:',df)

# 均值填充缺失值
df_mean = df.price.fillna(df.price.mean())
# price_mean = df.price.mean()
# # df_mean = df['price'].fillna(price_mean)
print(df_mean)
# df.price = df_mean
# print(df)

# 使用中位数进行填充缺失值
df_median = df.price.fillna(df.price.median())
print(df_median)
df.price = df_median
print(df)


# 使用众数进行填充
# 众数返回的是Series对象,需要通过索引获取值
df_mode = df.price.fillna(df.price.mode()[0])
print(df_mode)
# df.price = df_mode
# print(df)

案例:stock股票数据画图

需要导入tushare 和 seaborn模块

查看600848这支股票的数据并画图

from datetime import date
import matplotlib.pyplot as plt
import seaborn as sns
import tushare as ts

def draw_close(code):
    """
    1.近一个月股票收盘价走势图
    2.5日、10日以及20日均线
    3.每日收盘价涨跌幅度,diff(差值)/pct_change(涨/跌幅度百分比)
    :param code:
    :return:
    """
    # 数据准备与样式设置
    sns.set(style='whitegrid')
    plt.rcParams['font.sans-serif'] = ['SimHei']
    end = date.today() # 日期对象
    start = date(end.year, end.month-1, end.day) # 日期对象
    end = str(end)
    start = str(start)
    # 获取股票过去一个月的数据
    df = ts.get_hist_data(code, start, end)
    print(df)

    # 创建子图
    ax1 = plt.subplot(3,1,1)
    # 获取收盘价,绘制子图
    df['close'].plot(label='收盘价')
    df['open'].plot(label='开盘价')
    ax1.set_title('%s股票收盘价/收盘价走势曲线' %(code))
    ax1.legend(loc='upper right')

    # 创建子图
    ax2 = plt.subplot(3, 1, 2)
    ax2.set_title('%s股票均线走势曲线' %(code))
    df['ma5'].plot()
    df['ma10'].plot()
    df['ma20'].plot()
    ax2.legend(loc='upper right')

    # 创建子图
    ax3 = plt.subplot(3,1,3)
    ax3.set_title('%s股票每日涨跌幅度曲线'%(code))
    df['Daily Return'] = df['close'].pct_change()
    df['Daily Return'].plot()
    # ax3.legend(loc='upper right')


    plt.show()
if __name__ == '__main__':
    draw_close('600848')

在这里插入图片描述

量化股票提醒系统

项目描述:
1、实时获取股票数据
2、连接邮件服务器
3、预警配置管理
4、监控数据并发送邮件
最终通过实时提醒,来提高交易的收益率。结合crontab定时任务,每天9.30开始执行脚本
from datetime import datetime
from time import sleep
import tushare as ts

# 实时获取股票数据
def get_cur_price(code):
    """

    :param code:
    :return:
    """
    #获取实时交易数据 getting real time quotes data
    # 用于跟踪交易情况(本次执行的结果-上一次执行的数据)
    df = ts.get_realtime_quotes(code)
    name, price, high, low, time = df.name[0], float(df.price[0]), float(df.high[0]), float(df.low[0]), df.time[0]
    return name, price, high, low, time

# 2、连接邮件服务器,发送邮件
def send_email(to,title,text):
    """发送邮件"""
    print('收件人: %s 主题: %s 邮件正文: %s'%(to,title,text))

# 3、预警的配置管理
class Setting:
    max_price = 19
    min_price = 18
    send_user = 'sender@qq.com'
    to_user = 'receiver@qq.com'
    code = '600848'

# 4、监控数据并发送邮件
while True:
    # 特殊的设置:如果是周六周天或者周内的9:30-15:30除外
    today = datetime.now() #2020-05-02 23:27:36.144166
    weekday = today.weekday() # 0-周一 。。。。5-周六
    trade_start_time = datetime(year=today.year, month=today.month, day=today.day,
                                hour=9, minute=30,second=0)
    trade_end_time = datetime(year=today.year, month=today.month, day=today.day,
                                hour=15, minute=30, second=0)
    #周六周天不交易
    if weekday == 5 or weekday == 6:
        print('[交易停止] 节假日周六周天不交易')
        break
    # 9.30到15.30不交易
    if today < trade_start_time or trade_end_time < today:
        print('[交易停止] 交易时间9:30 - 15:30,当前时间:%s' %(today))
        break

    # 逻辑判断
    name, price, high, low, time = get_cur_price(Setting.code)
    print('>>{} price {}'.format(time, price))
    text_format = '股票{} 价格{} 最高价{} 最低价{}'
    if price < Setting.min_price:
        title = '%s股票下跌提醒' %(name)
        text = text_format.format(name, price, high, low)
        send_email(Setting.to_user, title=title, text=text)

    if price > Setting.max_price:
        title = '%s股票上涨提醒' %(name)
        text = text_format.format(name, price, high, low)
        send_email(Setting.to_user, title=title, text=text)

    sleep(3)

K近邻分类算法

# 导入数据生成器
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt

# 生成数据集
# random_state随机种子,保证每次随机生成的样本信息一致
X,y = make_blobs(n_samples=100, n_features=2, centers=2, random_state=8)

# 通过散点图,清楚的看到分为2类
plt.scatter(X[:,0], X[:,1], edgecolors='orange', color='white')
test_data = [6,3] # 测试集:测试模型好坏/正确率的数据集
plt.scatter(test_data[0], test_data[1], marker='*', color='r')
plt.show()

#如何去寻找一个模型,并最终根据模型预判断新的测试数据所属的分类
#机器学习:寻找一个函数/模型的过程
clf = KNeighborsClassifier()
clf.fit(X,y)  # 拟合(寻找模型的过程)

class_name = clf.predict([test_data])
print('新的数据点的分类是:',class_name)

在这里插入图片描述

K近邻的回归算法

import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_regression
from sklearn.neighbors import KNeighborsRegressor

# 产生回归的数据集(训练集)
X,y = make_regression(n_samples=100, n_features=1, n_informative=1,
                 noise=50, random_state=8)

# 通过K近邻的回归器,拟合/寻找模型
reg = KNeighborsRegressor()
reg.fit(X, y)

# 给定一些新的数据(测试集),预测y值
"""
np.linspace(-3,3,100)是一维数组
reshape(-1,1)生成n行1列的矩阵
reg.predict()需要的是n*1的数组
"""
test_x = np.linspace(-3,3,100).reshape(-1,1)
test_y = reg.predict(test_x)
print('模型的准确度:',reg.score(X,y))

# 解决中文乱码问题
plt.rcParams['font.sans-serif']=['SimHei']
# 绘制图形
plt.scatter(X,y, marker='*', color='r', edgecolors='orange', label='训练集')
plt.plot(test_x, test_y, color='black', label='测试集')
plt.title('KNN Regressor')
plt.legend()
plt.show()


模型的准确度: 0.7721167832505298

在这里插入图片描述
参考文档:

  1. https://www.jianshu.com/p/a93fe1423bc5
  2. https://blog.csdn.net/zw0Pi8G5C1x/article/details/84610050
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python---数据清洗 的相关文章

随机推荐

  • 使用ES6编写一个超简单的搜索算法

    自从chrome和ES6的普及 JS的性能和科学算法也日新月异 这次我就分享一个超简单的搜索算法 let result appData map item gt Object assign item count arr map i gt it
  • gulp安装那些事

    在Gulp中 使用的是Nodejs中的 stream 流 首先获取到需要的stream 然后可以通过stream的pipe 方法把流导入到你想要的地方 比如Gulp的插件中 经过插件处理后的流又可以继续导入到其他插件中 当然也可以把流写入到
  • 【电磁场计算】磁偶极子在外磁场中的受力

    磁偶极子在外磁场中的受力 背景 受力推导 矢量展开 结论 背景 最近在总结电磁场计算公式的时候发现 关于磁偶极子受力的计算公式 在不同文献中的说明有点出入 在此特地写一篇博客澄清一下 受力推导 通过磁偶极子在外磁场中的磁势能求梯度得出其受力
  • python虚拟环境的概念,配置和操作(pycharm为例)

    一 虚拟环境的由来和概念 1 在PyCharm中创建python项目时 需要配置python的运行环境 除了使用系统现有环境以外 还可以创建虚拟环境 2 虚拟环境的创建是因为在实际开发中需要同期用到不同版本的python解释器 不同的第三方
  • 微信小程序之蓝牙 BLE 踩坑记录

    前言 前段时间接手了一个微信小程序的开发 主要使用了小程序在今年 3 月开放的蓝牙 API 此过程踩坑无数 特此记录一下跳坑过程 顺便开了另一个相关的小项目 欢迎 start 和 fork BLE MiniProgram API简介 微信小
  • vue 富文本vue-quill-editor 自定义字号大小和字体样式

    一 先创建一个名为font的 css文件 然后引入自定义css 字体样式大小 ql snow ql picker ql font ql picker label data value SimSun before ql snow ql pic
  • Unity修改开始画面

    下面 是我换好的开始画面 中间的是开始淡入淡出画面的第一个 后面的是背景 还有就是如果不要最后的背景的话 那么就是一个纯色的背景 颜色可调
  • 干货!情感计算理论基础必看知识!!

    产生背景 在较长一段时期内 情感一直位于认知科学研究者的视线以外 直到20世纪末期 情感作为认知过程重要组成部分的身份才得到了学术界的普遍认同 当代的认知科学家们把情感与知觉 学习 记忆 言语等经典认知过程相提并论 关于情感本身及情感与其他
  • 假设检验之单个总体均值检验(含Python代码)

    什么是假设检验 教材原话 很容易理解 假设检验原理图 均值假设检验原理 理解重点 单个总体均值假设检验步骤 分位数的理解 附教材 统计量规定 单个总体检验的扩展 分为三类情况讨论 单侧检验 重点 Python代码 含例题答案 def zte
  • ./gophish: /lib64/libc.so.6: version `GLIBC_2.28‘ not found (required by ./gophish)

    本文向大家介绍Centos系统在启动一些服务的时候会碰到的 lib64 libc so 6 version GLIBC 2 28 not found required by 的问题的解决方法 根据提示可知碰到此问题 是因为没有找到GLIBC
  • ubuntu安装SLAM所需的库的方法

    一 安装Eigen3 安装步骤 从Github下载eigen3 git clone https github com eigenteam eigen git mirror sudo apt get install libeigen3 dev
  • 背包问题专题-动态规划

    目录 01背包问题 完全背包 多重背包 多重背包的优化 分组背包 01背包问题 有 N 件物品和一个容量是 V 的背包 每件物品只能使用一次 第 i 件物品的体积是 vi 价值是 wi 求解将哪些物品装入背包 可使这些物品的总体积不超过背包
  • Linux用户及用户组管理命令

    http blog sina com cn s blog 857e9db00101l6u7 html Linux用户及用户组管理命令 Linux系统是一个多用户多任务的分时操作系统 任何一个要使用系统资源的用户 都必须首先向系统管理员申请一
  • TCP原理之:TCP数据传输

    TCP原理之 TCP数据传输 TCP Transmission Control Protocol 全称为传输控制协议 它工作在网络七层模型中的第四层 传输层 是一种面向连接的可靠的数据传递协议 对于IP和UDP协议 它们会在接收到数据后根据
  • 钉钉如何实现原笔迹手写签批

    钉钉目前实现了简单的手写签字功能 与无纸化办公要求相比还有差距 在一些专业领域 特别时电子政务领域 原笔迹手写是作为最核心的功能之一 为实现原笔迹签批 通过外部应用来实现是明智之举 下面我来介绍一款无纸化办公的神器 这款独立的办公产品名称为
  • Linux查看当前目录下文件名中包含指定字符的文件

    find type f name edaijia 结果 转载于 https www cnblogs com wt645631686 p 8837163 html
  • Js 对象转数组对象 for...in

    遇到一个情况是需要把对象转成数组对象 用的是for in 不知道各位大佬们有没有其它方法可以贴出来学习学习 话不多说 直接贴代码和效果 let obj 未完成 5 已完成 8 待确认 4 已取消 6 let arr for let i in
  • 点击按钮button触发修改div的iframe内容 (修改iframe的src内容)

    新建一个html文件 比如test html 之后将如下内容复制进文件 然后用浏览器打开该html文件即可 table style height 100 width 100 tr td td tr table
  • 决策树系列4:随机森林 (三个臭皮匠顶个诸葛亮)

    引言 想了解一个人的人品一般询问多个熟悉他的人 而不是只问一个人 毕竟一个人的评价难免有失偏颇 对于决策树也是一样 单一的决策树有时候会过拟合 有时候效果不太理想 而随机森林就是利用多棵决策树共同做决策 毕竟三个臭皮匠顶个诸葛亮嘛 随机森林
  • python---数据清洗

    干净整洁的数据是后续进行研究和分析的基础 数据科学家们会花费大量的时间来清理数据集 毫不夸张地说 数据清洗会占据他们80 的工作时间 而真正用来分析数据的时间只占到20 左右 所以 数据清洗到底是在清洗些什么 通常来说 你所获取到的原始数据