前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >灰太狼的数据世界(三)

灰太狼的数据世界(三)

作者头像
我被狗咬了
发布2019-09-23 15:02:10
2.8K0
发布2019-09-23 15:02:10
举报
文章被收录于专栏:Python乱炖Python乱炖

一期我们了解了Pandas里面Series数据结构,了解了如何创建修改,清理Series,也了解了一些统计函数,例如方差,标准差,峰度这些数学概念。那么今天我们就来了解Pandas里面的另一个数据结构-----DataFrame。

DataFrame拆开的英文意思是数据框架。事实上它就是一个数据框架,一个类似于数据库中表一样的结构。

比如说我们现在有这样一张表,那么把这张表做成dataframe,先把每一列都提取出来,然后将这些在列的数据都放到一个大的集合里,在这里我们使用字典。(这里我们取姓名,年龄和收入这些字段)

代码语言:javascript
复制
代码语言:javascript
复制
import pandas as pd
data = {'Fname': ['amy', 'john', 'tony'],
        'age': [50, 55, 54],
        'income': [1000000, 500000, 400000000]}
df1 = pd.DataFrame(data)
print(df1)

这个时候我们看到这些数据做成的dataframe真的就像一个表一样,事实上它真的就是一张表。

我们把每一列数据都取出来,做成一个list(其实就是我们上期说的Series)。

如果我们想为这些数据添修改索引列(就是数据中的0,1,2),可以使用index参数指定索引。

代码语言:javascript
复制
df2 = pd.DataFrame(data, index=['A', 'B', 'C'], columns=['Fname', 'age', 'income'])
print(df2)

所以如果构造一个DataFrame,那就需要想好有哪几个列,把列对应的数据做成一个列表放进去。就可以了。说白了就是每个列都是一个Series,DataFrame = n * Series

下面我们来看看一些基础的称呼:

在pandas里面有一些基础的属性需要搞明白,这就和数据库差不多。我们对照数据来理解一下。dataframe里面有个属性叫index,那这个就是索引对应的也是数据库的索引,你也可以把它理解成主键。第二个属性是columns,这个就是一列。对应数据库的表也是一列。有多少个columns就有多少列了~第三个属性是rows,rows大家可以对比成数据的记录,有多少条记录就有多少rows。

当然,我们创建dateframe 的时候用的数据可能不是字典,可能就像是多个Series,想直接把它拼成dataframe,这样可以吗?

答案是可以的。我们可以直接使用多个Series去做出一个dataframe。

代码语言:javascript
复制
import pandas as pd
import numpy as np
s1 = np.array([1, 2, 3, 4])
s2 = np.array([5, 6, 7, 8])
df = pd.DataFrame([s1, s2])
print(df)

这就是我们上节课讲的,Series有默认索引,从零开始,那这个dataframe也就会和Series一样,如果不给他指定值(列名或索引),他就会从零开始计数。

我们工作中除了手动创建DataFrame,绝大多数数据都是读取文件获得的,例如读取csv文件,excel文件等等,那下面我们来看看pandas如何读取文件呢?

代码语言:javascript
复制
pd.read_csv(filename):从CSV文件导入数据
pd.read_table(filename):从限定分隔符的文本文件导入数据
pd.read_excel(filename):从Excel文件导入数据
pd.read_sql(query, connection_object):从SQL表/库导入数据
pd.read_json(json_string):从JSON格式的字符串导入数据
pd.read_html(url):解析URL、字符串或者HTML文件,抽取其中的tables表格
pd.read_clipboard():从你的粘贴板获取内容,并传给read_table()
pd.DataFrame(dict):从字典对象导入数据,Key是列名,Value是数据

pandas支持从多个数据源导入数据,包含文件,字典,json,sql,html等等。

那我们先来看看文件的导入:

我们创建一个csv文件,填写以上数据。

下面我们读取这个文件:

代码语言:javascript
复制
import pandas as pd
df = pd.read_csv("ex.csv")
print(df)

读出来的数据就是一个dataframe,可以直接对他进行操作。

如果想获取前几行值可以直接使用head方法,或者切片,都是可以拿到前两行的值的。读取数据的方法提供如下几种:

代码语言:javascript
复制
df.head(n):查看DataFrame对象的前n行
df.tail(n):查看DataFrame对象的最后n行
df.shape():查看行数和列数
df.info():查看索引、数据类型和内存信息
df.describe():查看数值列的汇总统计
s.value_counts(dropna=False):查看Series对象的唯一值和计数
df.apply(pd.Series.value_counts):查看DataFrame对象中每一列的唯一值和计数
代码语言:javascript
复制
print(df.head(2))
print(df[0:2])

读取excel:

代码语言:javascript
复制
import pandas as pd
score = pd.DataFrame(pd.read_excel('data.xlsx'))
score.to_excel('data1.xlsx')
print(score)

读取文件的示例就到这里,基本上每种文件都是一样的。

关于DataFrame里面还有一些修改表结构的操作,可以来适当了解一下:

代码语言:javascript
复制
import pandas as pd
import numpy as np
val = np.arange(10, 60).reshape(10, 5)
col = ["ax", "bx", "cx", "dx", "ex"]
idx = list("abcdefghij")
df1 = pd.DataFrame(val, columns = col, index = idx)
print(df1)
print("*" * 21, "<- dataframe")
df2 = df1.rename(columns={"ax": "修改1", "bx": "修改2"})
print(df2)
print("*" * 21, "<- dataframe")

通过rename方法来修改列名,本质上并没有修改原来的dataframe,而是生成新的dataframe替换了列名。

在DataFrame中增加一列,我们可以直接给值来增加一列,就和python的字典里面添加元素是一样的:

代码语言:javascript
复制
import pandas as pd
import numpy as np
val = np.arange(10, 60).reshape(10, 5)
col = ["ax", "bx", "cx", "dx", "ex"]
idx = list("abcdefghij")
df1 = pd.DataFrame(val, columns=col, index=idx)
print(df1)
nval = val = np.arange(100, 110).reshape(10, 1)
df1["fx"] = nval
print(df1)

连接多个dataframe,这个就和数据库一样,可以联想一下数据库之间的表连接,在dataframe里面我们使用contact方法。我们做的连接是全连接,如果数据不全的就会拿NaN来补:

代码语言:javascript
复制
import pandas as pd
import numpy as np
val1 = np.arange(10, 40).reshape(10, 3)
val2 = np.arange(50, 80).reshape(10, 3)
col1 = ["ax", "bx", "cx"]
col2 = ["cx", "dx", "ex"]
idx = list("abcdefghij")
df1 = pd.DataFrame(val1, columns=col1, index=idx)
df2 = pd.DataFrame(val2, columns=col2, index=idx)
print(df1)
print(df2)
df3 = pd.concat([df1, df2[5:], df1[:5], df2], axis=1)
print(df3)

如果不想做全连接,想做一些其他的连接,那我们在连接的时候可以使用merge方法,这样就可以进行不同的连接了。

代码语言:javascript
复制
import pandas as pd
df1 = pd.DataFrame({'name':['amy', 'john', 'a', 'b', 'c'], 'data1': range(5)})
df2 = pd.DataFrame({'name':['amy', 'john', 'A', 'B', 'C'], 'data2': range(5)})

# 指定 name 这列进行连接。
df3 = pd.merge(df1, df2, on='name')
# 内连接
df3 = pd.merge(df1, df2, how='inner')
# 左连接
df3 = pd.merge(df1, df2, how='left')
# 右连接
df3 = pd.merge(df1, df2, how='right')

在这后,我们需要做的就是处理数据了。把给定的一些数据处理好,这就看我们这些人是如何处理数据了。俗话说的好,条条大路通罗马。每个数据分析师都有自己处理数据的手段,最好能达到目的就可以了。

我们一开始拿到的原始数据多多少少是有些问题的,可能会丢失数据啊,有脏数据啊等等,这个时候需要我们来对数据进行一些清理。数据清洗是在数据准备的过程中必不可少的环节,pandas为我们提供了一系列清洗数据的方法。这里我们就来介绍一些。

首先我们可能需要从给定的数据中提取出一些我们想要的数据,而Pandas 提供了一些选择的方法,这些选择的方法可以把数据切片,也可以把数据切块。下面我们简单介绍一下:

选择一列:

data['column_name']

选择一列的前几行数据:

data['columns_name'][:n]

选择多列:

data[['column1','column2']]

Where 条件过滤:

data[data['column_name'] > condition]

那我们可以考虑一下产生这些异常数据的原因有哪些呢?

一般的,产生这个问题可能的原因可能有以下几点:

1、从来没有填正确过

2、数据不可用

3、计算错误

对于这些问题,我们处理这些异常数据无非就是下面几种办法:

1、为缺失数据赋值默认值

2、去掉/删除缺失数据行

3、去掉/删除缺失率高的列

添加默认值(fillna)

现在我们的数据中,年龄出现了异常值None,这个时候我们需要把None替换成标准的年龄值,我们假设研究对象的年龄平均在23左右,就把默认值设成23,那我们就可以成功的把None替换成23了。

代码语言:javascript
复制
import pandas as pd
data = {'Fname': ['amy', 'john', 'tony'],
        'age': [50, None, 54],
        'income': [1000000, 500000, 400000000]}
df1 = pd.DataFrame(data)
df1.age = df1.age.fillna(23)
print(df1)

删除不完整的行(dropna)

假设我们想删除任何有缺失值的行。这种操作具有侵略性,但是我们可以根据我们的需要进行扩展。

我们可以使用isnull来查看dataframe中是否有缺失值。

代码语言:javascript
复制
df1.isnull().values.any()

删除任何包含 NA 值的行是很容的:

代码语言:javascript
复制
df1.dropna() 

当然,我们也可以删除一整行的值都为 NA:

代码语言:javascript
复制
df1.dropna(how='all') 

我们也可以增加一些限制,在一行中有多少非空值的数据是可以保留下来的(在下面的例子中,行数据中至少要有 5 个非空值)

代码语言:javascript
复制
df1.drop(thresh=5) 

删除不完整的列(dropna)

我们可以上面的操作应用到列上。我们仅仅需要在代码上使用 axis=1 参数。这个意思就是操作列而不是行。(默认是axis=0。)

删除一整列为 NA 的列:

代码语言:javascript
复制
data.drop(axis=1, how='all')

删除任何包含空值的列:

代码语言:javascript
复制
data.drop(axis=1. how='any')

规范化数据类型

我们可以在读取文件的时候就限定,哪一列的数据是什么类型。

代码语言:javascript
复制
data = pd.read_csv('../data/moive.csv', dtype={'duration': int})

data = pd.read_csv('./data/moive.csv', dtype={'year':str})

还有一些注意点就是,当数据变成人为的破环,例如大写变小写,单词拼错等。使用一些方法来修复,具体是用正则还是其他方法,就看你了。

删除重复值(drop_duplicates)

表中难免会有一些重复的记录,这时候我们需要把这些重复的数据都删除掉。

代码语言:javascript
复制
import pandas as pd
data = {'Fname': ['amy', 'amy', 'john', 'tony'],
        'age': [50, 50, None, 54],
        'income': [1000000, 1000000, None, 400000000]}
df1 = pd.DataFrame(data)
print(df1.duplicated())
print(df1.drop_duplicates())

使用duplicated方法可以查找出是否有重复的行,使用drop_duplicated方法就可以直接将重复的行删除了。

关于dataframe中的统计函数,这里就不多说什么了,具体已经在Serires那个章节中列详细出来了。具体可以参考以下方法。

代码语言:javascript
复制
df.count()#非空元素计算
df.min()#最小值
df.max()#最大值
df.idxmin()#最小值的位置,类似于R中的which.min函数
df.idxmax()#最大值的位置,类似于R中的which.max函数
df.quantile(0.1)#10%分位数
df.sum()#求和
df.mean()#均值
df.median()#中位数
df.mode()#众数
df.var()#方差
df.std()#标准差
df.mad()#平均绝对
偏差df.skew()#偏度
df.kurt()#峰度
df.describe()#一次性输出多个描述性统计指标

下面我们说一下Pandas里面最神奇万能的apply函数。

apply函数可以对DataFrame对象进行操作,既可以作用于一行或者一列的元素,也可以作用于单个元素。apply最神奇的地方就是它里面可以调用函数,我们经常在apply里面写一些功能的匿名函数。

代码语言:javascript
复制
import pandas as pd
import numpy as np
s = pd.Series(np.arange(2, 6))
print(s)
print(s.apply(lambda x: 2 * x))

从上面例子的结果中我们看出数据里面的所有数字都被乘上了2,这就因为我们的apply函数里面写了一个匿名函数,将原来的数据变成两倍(如果你对lambda不懂,可以参考之前文章,介绍python里面的高级函数的

apply不仅可以适用于整个dataframe,也可以作用于行和列,如果想作用于行,可以添加参数axis=0,如果想作用于列,axis=1。

关于Pandas,我们到这里就算讲完了。欢迎大家前来交流和指点。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python乱炖 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档