像学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图形化工具创建数据库表。
目录
相关文章
|
1月前
|
SQL 自然语言处理 数据库
【Azure Developer】分享两段Python代码处理表格(CSV格式)数据 : 根据每列的内容生成SQL语句
本文介绍了使用Python Pandas处理数据收集任务中格式不统一的问题。针对两种情况:服务名对应多人拥有状态(1/0表示),以及服务名与人名重复列的情况,分别采用双层for循环和字典数据结构实现数据转换,最终生成Name对应的Services列表(逗号分隔)。此方法高效解决大量数据的人工处理难题,减少错误并提升效率。文中附带代码示例及执行结果截图,便于理解和实践。
|
25天前
|
XML JSON API
淘宝商品详情API的调用流程(python请求示例以及json数据示例返回参考)
JSON数据示例:需要提供一个结构化的示例,展示商品详情可能包含的字段,如商品标题、价格、库存、描述、图片链接、卖家信息等。考虑到稳定性,示例应基于淘宝开放平台的标准响应格式。
|
1天前
|
数据采集 NoSQL 关系型数据库
Python爬虫去重策略:增量爬取与历史数据比对
Python爬虫去重策略:增量爬取与历史数据比对
|
5天前
|
数据采集 存储 缓存
Python爬虫与代理IP:高效抓取数据的实战指南
在数据驱动的时代,网络爬虫是获取信息的重要工具。本文详解如何用Python结合代理IP抓取数据:从基础概念(爬虫原理与代理作用)到环境搭建(核心库与代理选择),再到实战步骤(单线程、多线程及Scrapy框架应用)。同时探讨反爬策略、数据处理与存储,并强调伦理与法律边界。最后分享性能优化技巧,助您高效抓取公开数据,实现技术与伦理的平衡。
30 4
|
12天前
|
存储 监控 算法
基于 Python 哈希表算法的局域网网络监控工具:实现高效数据管理的核心技术
在当下数字化办公的环境中,局域网网络监控工具已成为保障企业网络安全、确保其高效运行的核心手段。此类工具通过对网络数据的收集、分析与管理,赋予企业实时洞察网络活动的能力。而在其运行机制背后,数据结构与算法发挥着关键作用。本文聚焦于 PHP 语言中的哈希表算法,深入探究其在局域网网络监控工具中的应用方式及所具备的优势。
44 7
|
20天前
|
存储 数据库 Python
利用Python获取网络数据的技巧
抓起你的Python魔杖,我们一起进入了网络之海,捕捉那些悠游在网络中的数据鱼,想一想不同的网络资源,是不是都像数不尽的海洋生物,我们要做的,就是像一个优秀的渔民一样,找到他们,把它们捕获,然后用他们制作出种种美味。 **1. 打开魔法之门:请求包** 要抓鱼,首先需要一个鱼网。在Python的世界里,我们就是通过所谓的“请求包”来发送“抓鱼”的请求。requests是Python中常用的发送HTTP请求的库,用它可以方便地与网络上的资源进行交互。所谓的GET,POST,DELETE,还有PUT,这些听起来像偶像歌曲一样的单词,其实就是我们鱼网的不同方式。 简单用法如下: ``` im
53 14
|
15天前
|
数据采集 搜索推荐 API
Python 原生爬虫教程:京东商品列表页面数据API
京东商品列表API是电商大数据分析的重要工具,支持开发者、商家和研究人员获取京东平台商品数据。通过关键词搜索、分类筛选、价格区间等条件,可返回多维度商品信息(如名称、价格、销量等),适用于市场调研与推荐系统开发。本文介绍其功能并提供Python请求示例。接口采用HTTP GET/POST方式,支持分页、排序等功能,满足多样化数据需求。
|
16天前
|
数据采集 存储 JSON
用Python爬虫抓取数据并保存为JSON的完整指南
用Python爬虫抓取数据并保存为JSON的完整指南
|
1月前
|
人工智能 编解码 算法
如何在Python下实现摄像头|屏幕|AI视觉算法数据的RTMP直播推送
本文详细讲解了在Python环境下使用大牛直播SDK实现RTMP推流的过程。从技术背景到代码实现,涵盖Python生态优势、AI视觉算法应用、RTMP稳定性及跨平台支持等内容。通过丰富功能如音频编码、视频编码、实时预览等,结合实际代码示例,为开发者提供完整指南。同时探讨C接口转换Python时的注意事项,包括数据类型映射、内存管理、回调函数等关键点。最终总结Python在RTMP推流与AI视觉算法结合中的重要性与前景,为行业应用带来便利与革新。
|
30天前
|
Web App开发 数据采集 前端开发
Python + Chrome 爬虫:如何抓取 AJAX 动态加载数据?
Python + Chrome 爬虫:如何抓取 AJAX 动态加载数据?

热门文章

最新文章

下一篇
oss创建bucket