像学R一样学Python数据分析之基本数据管理

本文涉及的产品
数据管理 DMS,安全协同 3个实例 3个月
推荐场景:
学生管理系统数据库
简介: 两种基本数据结构pandas具有两种主要的数据结构,一种叫做 Series, 直译就是序列, 另一种叫做 DataFrame, 直译就是数据框。这两者与Python内置的数据结构,以及Numpy的ndarray数据结构最大的不同就在于,它们是由数据和数据标签组成。

两种基本数据结构

pandas具有两种主要的数据结构,一种叫做 Series, 直译就是序列, 另一种叫做 DataFrame, 直译就是数据框。

这两者与Python内置的数据结构,以及Numpy的ndarray数据结构最大的不同就在于,它们是由数据和数据标签组成。说人话就是,它们让Python成为了一个Excel。其中 DataFrane 简单理解就是多列的 Series

一个示例

这里用R语言实战第二版的一个案例

本人当前工作的研究主题之一是男性和女性在领导各自企业方式上的不同。典型的问题如下。

  • 处于管理岗位的男性和女性在听从上级的程度上是否有所不同?
  • 这种情况是否依国家的不同而有所不同,或者说这些由性别导致的不同是否普遍存在?
img_22d82939b0d2511d643d7071b1152d2a.png
案例数据

要解决的问题如下:

  • 五个评分(q1到q5)需要组合起来,即为每位经理人生成一个平均服从程度得分。
  • 在问卷调查中,被调查者经常会跳过某些问题。例如,为4号经理人打分的上司跳过了问题4和问题5。我们需要一种处理不完整数据的方法,同时也需要将99岁这样的年龄值重编码为缺失值
  • 一个数据集中也许会有数百个变量,但我们可能仅对其中的一些感兴趣。为了简化问题,我们往往希望创建一个只包含那些感兴趣变量的数据集。
  • 既往研究表明,领导行为可能随经理人的年龄而改变,二者存在函数关系。要检验这种观点,我们希望将当前的年龄值重编码为类别型的年龄组(例如年轻、中年、年长)。
  • 领导行为可能随时间推移而发生改变。我们可能想重点研究最近全球金融危机期间的服从行为。为了做到这一点,我们希望将研究范围限定在某一个特定时间段收集的数据上(比如,2009年1月1日到2009年12月31日)。

创建数据集

根据表格,手动创建Series,DataFrame,

from pandas import Series, DataFrame
from numpy import nan as NA
import pandas as pd
import numpy as np
# 创建Series
manager = Series([1,2,3,4,5])
country = Series(['US','US','UK','UK','UK'])
gender = Series(['M','F','F','M','F'])
age = Series([32,45,25,39,99])
q1 = Series([5,3,3,3,2])
q2 = Series([4,5,5,3,2])
q3 = Series([5,2,5,4,1])
q4 = Series([5,5,5,NA,2])
q5 = Series([5,5,2,NA,1])
# 由Series组成DataFrame
leadership = DataFrame({'manager':manager,'country':country,'gender':gender,'age':age,
'q1':q1,'q2':q2,'q3':q3,'q4':q4,'q5':q5})

如果数据没有写完,增加额外列,

date = Series(['10/24/08','10/28/08','10/1/08','10/12/08','5/1/09'])
# 为不存在的列赋值能够创建新的一列。
leadership['date'] = date
# 查看数据库的值
leadership.values
# 查看前后几行
leadership.head(2)
leadership.tail(2)

手动创建数据的情况比较少,我们用pandas自带的读取函数导入一个以制表符分隔的格式化的文本文件,然后看下数据结构。
原始数据有20列29850行,为10个对照组10个控制组在29850个基因上的表达量。

img_1919adad4259cb3c8e3801313cc9218d.png
  • 读取数据,
In [1]: import pandas as pd
In [2]: data = pd.read_table("C:/Users/Xu/Desktop/Data.txt")
In [3]: type(data)
Out[3]: pandas.core.frame.DataFrame
  • 简单查看数据
# 数据框大小
In [4]: data.shape
Out[4]: (29849, 21)
# 前两行
In [5]: data.head(2)
Out[5]: 
  Unnamed: 0  control1  control2  control3  control4  control5  control6  \
0       A1BG  6.917468  6.308350  5.318841  5.886811  5.082975  5.629453
1   A1BG-AS1  7.862730  7.065809  6.783732  6.275773  3.063104  5.131017

在继续介绍数据管理前,先简单介绍一下panda的index对象。pandas使用索引对象管理轴标签(行列名),它不可被轻易修改。因为Index对象的存在,不同来源的数据能够进行对齐,还能根据索引重新排序。

  • 选取数据框元素, 就是能够提取某几行,某几列,或者某一个元素。
# 按行选取元素, 提供单个索引,或者是list
leadership.ix[1]
leadership.ix[[1,2,3]] # 或leadership.ix[1:3]
# 按列选取元素
leadership[[1,2,3]]
leadership[[1]]
leadership['q1']
leadership.ix[:,1:3] 
## 特别的,还可以根据列名,选取一个范围
leadership.ix[:,'q1':'q5']

# 按行,按列,选取局部元素, [行,列]
leadership.ix[1,2]
leadership.ix[1:2,2:3]
leadership.ix[1:3,2:4]

: Python以0为基, 所以leadership.ix[[1]]选取的是第二行,并且leadership.ix[1:3]是优先根据索引名,而leadership[1:3]则是根据位置顺序。 目前来看直接用[]有很多小问题,所以建议都改用ix[]

基本数据管理

下面使用的数据来自于前面导入的data, 模仿《R语言实战》的基本数据管理章节编排。

创建新变量

比如说新建一个总分,是q1-q5的总计

# 用到numpy的通用数学函数, 其中axis=0表示每一列的计算结果,axis=1表示所有行的运算结果
In [29]: total = np.sum(leadership.ix[:,'q1':'q5'], axis=1)
In [30]: total
Out[30]: 
0    24.0
1    20.0
2    20.0
3    10.0
4     8.0
dtype: float64
## np.sum计算的时候会无视掉缺失值NA
# 可以直接增加到数据框内
leadership['total'] = np.sum(leadership.ix[:,'q1':'q5'], axis=1)

变量重编码

重编码涉及到同一变量和/或其他变量的现有值创建新值的过程。比如说,将一个连续性变量修改为一组类别值;将误编码的值替换成正确值;基于一组分数线创建一个表示及格/不及格的变量。

比如说在leadership里面的年龄中有一个是99岁,按照尝试来看就是错的,所以需要把他重编码为NA。

# 方式一
## .ix 比 .loc使用更加广泛,对于初学者来说没有差异
leadership['age'][leadership['age'] > 99] = NA
leadership.ix[:,'age'][leadership.ix[:,'age'] >= 99] = NA
leadership.loc[:,('age')][leadership['age'] == 99] = NA
# 方式二
leadership.ix[leadership['age'] > 99,'age'] = NA
leadership.loc[leadership['age'] == 99, 'age']

看起来第一种方法用了很多,但是都属于chained indexing, 直译就是连锁索引,也就是连续用了[]。这个其实我沿用了R语言的习惯,leadership$age[leadership$age == 99],pandas在处理chained indexing如果发现存在赋值现象,就会报错或者警告。

问题来自于底层Python代码处理chained indexing时是返回视图(views)还是复制(copy),毕竟还会导致性能上的降低。所以建议第二种。

注: 视图和复制是两个不同的概念,如果你将视图赋值给新变量,对新变量的操作会影响到原始数据,而如果将原始数据的一个复制赋值给新变量,那么对新变量的操作就与原始数据无关。

下一步,我们还可以把大于75定义为older, 55和75间定义为midlle aged, 小于55则是young。

leadership['agecat'] = np.where(leadership['age'] > 75, 'Elder', np.where(np.logical_and(leadership['age']<=75, leadership['age'] >= 45), "Middle Aged", "Young" ))

这里用到Numpy的人二元ufunc中的元素级比较运算, np.where,np.logical_and。如果用np.greater和np.less,会遇到报错,这是因为存在缺失值。

变量重命名

如果对现有的名字不满意,可以对行名(index),列名(columns)进行修改

# 先查看列名
leadership.columns
# 函数采用rename, 参数为columns, index,可以用字典指定置换映射
leadership = leadership.rename(columns={'q1': 'item1','q2':'item2','q3':'item3','q4':'item4','q5':'item5'})

缺失值处理

真实世界的数据有可能存在残缺,在pandas中庸NaN表示缺失或NA值,用isnull和notnull函数进行检测

# 查看是否有缺失
pd.isnull(leadership)
pd.notnull(leadership)
## 或
leadership.isnull()
leadership.notnull()

缺失值的处理方法简单分为两种,一种是过滤,dropna或者是填充,fillna
如果缺失部分较少,剔除后对结果没有影响,采用第一种,否则用第二种。

# 默认是axis=0, how='any',也就是提出有一个是NA的行
newdata = leadership.dropna()
# 按列剔除
leadership.dropna(axis=1)
# 仅剔除都是NA所在行
leadership.dropna(axis=1, how='all')
# inplace表示是否原始数据上操作
leadership.dropna(axis=1, how='all', inplace=True)

关于插值,比较复杂,以后讲解

日期值

Python标准库自带日期(date)和时间(time)数据的数据类型,主要用的是dateime, time, calenda模块,在其中datetime.datetime是用得最多数据类型。pandas用to_datetime解析不同日期的表达方式。

# pd.to_datetime
leadership['date'] = pd.to_datetime(leadership['date'])

更多和日期值相关的内容留待时间序列部分介绍。

类型转换

变量可以用isstance进行判断, 判断所属对象

isinstance(leadership, DataFrame)
# True

数据结构之间的转变,则直接用对应的构建函数即可

isinstance(leadership['item5'], Series)
# True
np.array(leadership['item5'])
# array([5, 5, 2, 1], dtype=int64)

查看数据类型则可以用.dytpe

leadership['date'].dtype
# dtype('<M8[ns]')

而数据类型转换可以用.astype完成

leadership['item5'].dtype
# dtype('float64')
leadership['item5'] = leadership['item5'].astype(np.int64)

数据排序

pandas排序可以根据索引(by index),也可以根据数值(by values)
如果根据索引,分为行名(axis=0)或者是列名(axis=1)

## 首先用reindex打乱顺序
unsorted = leadership.reindex(index=[4,2,1,3,0])
## 用sort_index()排序,参数有ascending,inplace, axis
resorted = leadership.sort_index()

如果根据数值, 可以提供多个列,然后指定每列的升降序

leadership.sort_values(by=['item1','item2'], ascending=[False,True])

数据集的合并

数据集的合并分为添加列或是添加行。pandas具备按轴(行或列)自动或显式数据对其功能。并且底层是C编写,所以处理合并速度极快。以官方文档为例, 主要回到两个函数pd.concatpd.appendpd.merge

  • pd.merge 可以根据一个或多个键将不同的DataFrame中的行链接起来,类似于R的merge,但是速度更快
  • pd.concat 可以根据一条轴将多个对象堆叠在一起。

对于pd.merge而言,如果用过R语言的merge或者是SQL等关系型数据库的连接操作,基本上能很快理解。

df1 = DataFrame({'key':['b','b','a','c','a','a','b'], 'data1':range(7)})
df2 = DataFrame({'key':['a','b','d'], 'data2':range(3)})
# 没有显示指明键
pd.merge(df1,df2)
# 使用on,进行指明,如果左右不同,则需要用left_on, right_on指定
pd.merge(df1, df2, on='key')

对于数据库类型,有4种连接方式要注意,inner, outer, left, right。看下图进行了。

img_f509d933391ad9badf63615bcc5acfc4.png
merge

而另一类pd.concat则是根据轴的标签进行合并。

s1 = Series([0,1], index=['a','b'])
s2 = Series([2,3,4], index=['c','d','e'])
s3 = Series([5,6], index=['f','g'])
pd.concat([s1,s2,s3], axis=1)

合并操作可以用来完成生信编程直播第四题:多个同样的行列式文件合并起来

第一步,下载操作数据,并解压

wget ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE48nnn/GSE48213/suppl/GSE48213_RAW.tar
tar -x GSE48213_RAW.tar
gzip -d *.gz
mkidr GSE48213_RAW
mv *.txtGSE48213_RAW

第二步,合并数据
使用pd.merge的代码搬运自生信技能树用户end2end

import pandas
import os
name_list=os.listdir("GSE48213_RAW")
fram_list=[pd.read_table("GSE48213_RAW/%s"%name) for name in name_list]
fram=fram_list[0]
for i in range(1,len(fram_list)):
    fram=pandas.merge(fram,fram_list[i])
fram.to_csv("result.csv",index=False)

如果在读取表格的时候设置基因名为轴索引(行名),那么就可以用pd.concat

import pandas as pd
import os
name_list=os.listdir("GSE48213_RAW")
each = [pd.read_table("GSE48213_RAW/%s"%name,header=0,index_col=0) for name in name_list]
total  = pd.concat(each, axis=1)
total.to_csv("result.csv",index=True)

数据集取子集

这部分内容在前面有所提及,这里在基础上继续介绍

  • 选入(保留)变量,可以认为是选择列
    选入变量,可以通过DataFrame.ix[行索引, 列索引]这样记号来访问
new_data =  leadership.ix[:,6:10]

其中:,表示选取所有行。

如果是直接选取某一个列,pandas用.对应R的$

leadership.date
0   2008-10-24
1   2008-10-28
2   2008-10-01
4   2009-05-01
Name: date, dtype: datetime64[ns]
  • 剔除(丢弃)变量
    比如说我们想剔除q3和q4两列
myvars = leadership.columns.isin(['item4','item5'])
new_data = leadership.ix[:,np.logical_not(myvars)]
  • 选入观测
    选入或剔除观测(行)通常是成功的数据准备和数据分析的一个关键方面。比如说让我们选取30岁以上的男性
leadership.ix[np.logical_and(leadership.gender == 'M', leadership.age > 30),:]

你会感觉这样写代码太长了,我们需要一个类似R的subset的函数,在pandas对应的是query.

leadership.query('age <35 and gender == "M"')
  • 随机抽样
    pandas提供了sample方法用于对样本进行抽样。
leadership.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
# replace表示是否放回。
# 可以按数量
leadership.sample(n=2, replace=True)
# 可以按照比例
leadership.sample(frac=0.5, replace=True)

小结

本文讲解了大量的基础知识。我们以R语言实战的一个数据为例,讲解了如何在Python如何创建一个DataFrame对象(手动或导入),然后根据已有变量创建新变量,对变量重编码,重命名变量。之后是缺失数据的处理,对于pandas,这部分介绍用dropna按行或按列丢弃,然后是日期值部分。 关于数据转换,分为数据结构和数据类型两部分。之后介绍了数据合并,并且以表达量矩阵合并为例实际操作,最后是数据取子集和抽样。

当我们学会基本的数据处理之后,我们接着就可以根据不计其数函数进行更高级的操作。

当你看完后续的部分,你就能掌握复杂数据集的多数工具。无论你走到哪里,都将成为数据分析师艳羡的人物!

相关实践学习
MySQL基础-学生管理系统数据库设计
本场景介绍如何使用DMS工具连接RDS,并使用DMS图形化工具创建数据库表。
目录
相关文章
|
4天前
|
数据采集 数据可视化 数据挖掘
基于Python的数据分析与可视化实战
本文将引导读者通过Python进行数据分析和可视化,从基础的数据操作到高级的数据可视化技巧。我们将使用Pandas库处理数据,并利用Matplotlib和Seaborn库创建直观的图表。文章不仅提供代码示例,还将解释每个步骤的重要性和目的,帮助读者理解背后的逻辑。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供有价值的见解和技能。
18 0
|
3天前
|
JSON 安全 数据安全/隐私保护
深度剖析:Python如何运用OAuth与JWT,为数据加上双保险🔐
【10月更文挑战第2天】当讨论Web应用安全时,认证与授权至关重要。OAuth 2.0 和 JSON Web Tokens (JWT) 是现代Web应用中最流行的两种认证机制。OAuth 2.0 是一种开放标准授权协议,允许资源拥有者授予客户端访问资源的权限,而不需直接暴露凭据。JWT 则是一种紧凑、URL 安全的信息传输方式,自我包含认证信息,无需服务器查询数据库验证用户身份。在 Python 中,Flask-OAuthlib 和 PyJWT 分别用于实现 OAuth 2.0 和 JWT 的功能。结合两者可构建高效且安全的认证体系,提高安全性并简化交互过程,为数据安全提供双重保障。
17 7
|
2天前
|
数据采集 存储 监控
如何使用 Python 爬取商品数据
如何使用 Python 爬取京东商品数据
17 3
|
1天前
|
数据采集 机器学习/深度学习 数据挖掘
数据也需SPA?Python转换大法,给你的数据做个全身放松SPA!
【10月更文挑战第4天】在数字化时代,数据犹如企业的血液,贯穿于各项业务之中。就像人需要定期SPA恢复活力,数据也需要“转换大法”来优化结构和提升质量,从而更好地支持决策分析与机器学习。本文探讨了如何使用Python进行数据SPA,包括理解需求、数据清洗、格式转换及聚合分析等步骤。通过Python强大的Pandas库,我们可以轻松完成缺失值填充、重复记录删除等任务,并实现数据格式的标准化,确保数据更加整洁、有序,助力高效分析与决策。为企业数据注入新的活力,迎接更多挑战。
10 1
|
2天前
|
数据采集 存储 监控
如何使用 Python 爬取京东商品数据
如何使用 Python 爬取京东商品数据
12 2
|
4天前
|
数据采集 机器学习/深度学习 存储
使用 Python 清洗日志数据
使用 Python 清洗日志数据
14 2
|
6天前
|
Python
Python编程案例:同一工作簿不同表单特定数据添加到工作簿的另一表单里
Python编程案例:同一工作簿不同表单特定数据添加到工作簿的另一表单里
11 1
|
1天前
|
数据采集 监控 数据可视化
用Python构建动态折线图:实时展示爬取数据的指南
本文介绍了如何利用Python的爬虫技术从“财富吧”获取中国股市的实时数据,并使用动态折线图展示股价变化。文章详细讲解了如何通过设置代理IP和请求头来绕过反爬机制,确保数据稳定获取。通过示例代码展示了如何使用`requests`和`matplotlib`库实现这一过程,最终生成每秒自动更新的动态股价图。这种方法不仅适用于股市分析,还可广泛应用于其他需要实时监控的数据源,帮助用户快速做出决策。
|
2天前
|
数据采集 数据可视化 数据挖掘
Python 数据分析实战:使用 Pandas 进行数据清洗与可视化
【10月更文挑战第3天】Python 数据分析实战:使用 Pandas 进行数据清洗与可视化
13 0
|
2天前
|
Android开发 Swift iOS开发
python 基于电脑蓝牙连接获取手机的实时数据
python 基于电脑蓝牙连接获取手机的实时数据
8 0