美文网首页
day80-数据清洗及数据库连接

day80-数据清洗及数据库连接

作者: barriers | 来源:发表于2019-03-08 20:26 被阅读0次

1数据清洗

1.1缺失数据处理

isnull检测缺失值;dropna删除缺失值;python内置的none值在对象数组中也可以作为na值

string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
string_data.isnull()  # 检测空值
data.dropna()  # 删除空值
data[data.notnull()]  # 提取出不是空值的数据

DataFrame对象,dropna默认丢弃任何含有缺失值的行(只要有na就删除);传入how=‘all’将只丢弃全为NA的那些行

cleaned = data.dropna()
data.dropna(how='all') 
data.dropna(axis=1, how='all') #删除列上全为空的列

df.iloc[:4, 1] = NA #将1-4行,第2列的数据全置为na
df.dropna(thresh=2) # 删除大于等于2个非空值的行

1.2缺失数据填充

填充缺失数据中fillna方法是主要的函数。通过一个常数调用fillna就会将缺失值替换为那个常数值。通过字典调用,可以实现对不同的列填充不同的值

df.fillna(0) # 将na值填充为0
df.fillna({1: 0.5, 2: 0})  # 第2列缺失填0.5,第三列缺失填0

fillna默认会返回新对象,但也可以对现有对象进行就地修改

_ = df.fillna(0, inplace=True)

对reindexing有效的那些插值方法也可用于fillna(如轴标签loc和整数索引iloc及前向填充等)

df.fillna(method='ffill') #对na值用前向填充
df.fillna(method='ffill', limit=2)  # 最多前向填充两个

填充series的平均值或中位数

data = pd.Series([1., NA, 3.5, NA, 7])
data.fillna(data.mean())  # 有值就用原值,没有就用有数据的平均数

1.3删除重复数据

data = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'],  'k2': [1, 1, 2, 3, 3, 4, 4]})
data.duplicated()  # 前向比较,与前项相同就标为true
data.drop_duplicates()  # 删除与前项相同的数据
data.drop_duplicates(['k1'])  # 根据k1列过滤重复项
data.drop_duplicates(['k1', 'k2'], keep='last') 

drop_duplicates方法,它会返回一个DataFrame,重复的数组会标为False;duplicated和drop_duplicates默认保留的是第一个出现的值组合。传入keep=‘last’则保留 后一个

1.4利用函数或映射进行数据转换

根据数组、Series或DataFrame列中的值来实现转换工作

data = pd.DataFrame({'food': ['bacon', 'pulled pork'], 'ounces': [4, 3,]})

添加一列表示该肉类食物来源的动物类型。我们先编写一个不同肉类到动物的映射

meat_to_animal = {  'bacon': 'pig',  'pulled pork': 'pig'}
lowercased = data['food'].str.lower() # 使用Series的str.lower方法;字母转小写
data['animal'] = lowercased.map(meat_to_animal) # 映射

也可以传入一个能够完成全部这些工作的函数

data['food'].map(lambda x: meat_to_animal[x.lower()]) 

1.5替换

-999这个值可能是一个表示缺失数据的标记值。要将其替换为pandas能够理解的NA值(使用replace)

data = pd.Series([1., -999., 2., -999., -1000., 3.])
data.replace(-999, np.nan) 
data.replace([-999, -1000], np.nan)  # 一次性替换两种数据
data.replace([-999, -1000], [np.nan, 0])  # 每种数据对应不同的替换类型
data.replace({-999: np.nan, -1000: 0})  # 也是替换两种数据

1.6重命名轴索引

transform = lambda x: x[:4].upper() # 将行的索引切前四个并全部大写
data.index.map(transform)  # 替换行的索引

如果想要创建数据集的转换版(而不是修改原始数据)

data.rename(index=str.title, columns=str.upper) 

rename可以结合字典型对象实现对部分轴标签的更新;或者就地修改某个数据集,传入inplace=True即可

# 将OHIO换成INDIANA。three换成peekaboo
data.rename(index={'OHIO': 'INDIANA'},  columns={'three': 'peekaboo'}) 
data.rename(index={'OHIO': 'INDIANA'}, inplace=True) # 修改OHIO为INDIANA

1.7离散化和面元划分

为了便于分析,连续数据常被离散化或拆分为“面元”(bin)。
分隔后的参数默认为前开后闭,可以对cut进行设置right=False使其前闭后开

ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]  #年龄表
bins = [18, 25, 35, 60, 100] # 年龄段划分的断点
cats = pd.cut(ages, bins) # 划分年龄,返回的是年龄对应的每个年龄段
pd.value_counts(cats)  # 统计每个区间的人的个数
pd.cut(ages, [18, 26, 36, 61, 100], right=False)  # 切割成前闭后开的类型

group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
pd.cut(ages, bins, labels=group_names)  # 给每个区间设置名称

向cut传入的是面元的数量而不是确切的面元边界,则它会根据数据的最小值和最大值计算等长面元。下面这个例子中,我们将一些均匀分布的数据分成四组,选项precision=2,限定小数只有两位。
qcut是一个非常类似于cut的函数,它可以根据样本分位数对数据进行面元划分。

pd.cut(data, 4, precision=2) 
cats = pd.qcut(data, 4)
pd.value_counts(cats)  # 统计个数

cut和qcut区别:cut是将区间进行均分,区间间隔相同,每个区间的数值个数不同 ;qcut是将每个区间的数值进行均分的数值处划分;区间间隔不同,每个区间的数值个数相同。

1.8检测和过滤异常值

describe() 统计每一列的个数,平均值,中位数,最大、最小值等;np.sign(data)可以生成1和-1

data = pd.DataFrame(np.random.randn(1000, 4))
data.describe()  # 统计每一列的个数,平均值,中位数,最大、最小值等

col = data[2] # 取出第三列
col[np.abs(col) > 3]  # 统计这列中绝对值大于3的数
data[(np.abs(data) > 3).any(1)]  # 选出全部含有超过-3或3的行
np.sign(data).head()  #生成1和-1

1.9排列和随机采样

利用numpy.random.permutation函数可以轻松实现对Series或DataFrame的列的排列工作 (permuting,随机重排序)

df = pd.DataFrame(np.arange(20).reshape((5, 4)))
sampler = np.random.permutation(5)
df.take(sampler)  # 按随机生成的sampler中的顺序对df进行重排序
df.sample(n=3)  # 随机排列3行(从df中随机取3行)

要通过替换的方式产生样本(允许重复选择),可以传递replace=True到sample

choices = pd.Series([5, 7, -1, 6, 4])
draws = choices.sample(n=10, replace=True)

1.10计算指标

df = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],'data1': range(6)})
pd.get_dummies(df['key']) # 取key列的数据,并将其作为列的索引,统计每一行出现的位置
dummies = pd.get_dummies(df['key'], prefix='key') # 统计并给索引加前缀key_

1.11从dat文件中读数据并写入数据库

在读取数据前,需要退出ipython环境,并运行conda install pymysql安装依赖库

# 连接数据库
db= sqla.create_engine('mysql+pymysql://root:123456@127.0.0.1/pdmovie?charset=utf8')
# 给读取的数据前索引,必须于数据库中的字段保持一致
mnames = ['movie_id', 'title', 'genres']    
# 读取数据
movies = pd.read_table('datasets/movielens/movies.dat', sep='::', header=None, 
    names=mnames, engine='python')
# 吸入数据库
movies.to_sql('movies', db,index=False, if_exists='append')

all_genres = []
# 遍历读取的数据中的genres列,实质上就是一个serise
for x in movies.genres:
    all_genres.extend(x.split('|'))
# 对切割后的电影类型去重
genres = pd.unique(all_genres)

构建指标DataFrame的方法之一是从一个全零DataFrame开始

zero_matrix = np.zeros((len(movies), len(genres)))
dummies = pd.DataFrame(zero_matrix, columns=genres)

通过data.map,所有字符串和正则表达式方法都能被应用于(传入lambda表达式或其他函数)各个值,但是如果存在NA(null)就会报错。为了了解决这个问题,Series有一些能够跳过 NA值的面向数组方法,进行字符串操作。通过Series的str属性即可访问这些方法。例如,我们可以通过str.contains检查各个电子邮件地址是否含有"gmail"

data = {'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com', 'Rob': 'rob@gmail.com', 'Wes': np.nan}
data = pd.Series(data)
data.str.contains('gmail')  # 查看是否含有gmail

矢量化字符串函数也可以使用正则表达式,还可以加上任意re选项(如IGNORECASE)

import re 
pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})' 
data.str.findall(pattern, flags=re.IGNORECASE)  # 按@和.符号将其切分为三个部分
matches = data.str.match(pattern, flags=re.IGNORECASE) # 使用match进行比对
data.str[:5]  # 对data中的每个字符串进行切片

相关文章

  • day80-数据清洗及数据库连接

    1数据清洗 1.1缺失数据处理 isnull检测缺失值;dropna删除缺失值;python内置的none值在对象...

  • 数据处理工具

    Navicat:连接数据库看数据的; Tableau:数据可视化图表呈现的; 数据清洗:openrefine;da...

  • pandas连接mysql

    首先,温习一个清空数据库表内容的命令 下面进入正题:(1)导入包 (2)sql语句及数据库连接 (3)在数据库连接...

  • JDBC连接数据库

    简要记录如下:具体代码,需将数据库连接及关闭封装为工具类 数据库连接信息采用配置文件 使用getClassLoad...

  • (3) spring-boot+druid+mybatis环境搭

    本文以druid数据库连接池及mybatis框架,搭建基本的应用开发框架。 1、druid数据库连接池 1.1、D...

  • PostgreSql连接池(psycopg2.pool)

    连接池的作用及原理 正常访问数据库的过程中,每次访问都需要创建数据库的连接,这会消耗大量的资源;连接池的就是为数据...

  • Ubuntu操作mysql数据库命令

    一、连接数据库 连接本地数据库 退出数据库 二、操作数据库 创建数据库 显示数据库 删除数据库 连接数据库 查看状...

  • EF数据库初始化策略及种子数据的添加

    EF数据库初始化策略及种子数据的添加 CreateDatabaseIfNotExists判断当前数据库连接字符串对...

  • servlet连接mysql数据库和oracle数据库

    连接mysql数据库 连接oracle数据库

  • SpringBoot配置MySQL多数据源

    1、先配置数据库连接文件 在连接文件中,设置多个数据库连接 2、AAA数据库连接配置文件 3、BBB数据库连接配置...

网友评论

      本文标题:day80-数据清洗及数据库连接

      本文链接:https://www.haomeiwen.com/subject/cgzrpqtx.html