一句Python,一句R︱pandas模块——高级版data.frame
先学了R,最近刚刚上手python,所以想着将python和R结合起来互相对比来更好理解python。最好就是一句python,对应写一句R。
pandas可谓如雷贯耳,数据处理神器。
以下符号:
=R=
代表着在R中代码是怎么样的。
pandas 是基于 Numpy 构建的含有更高级数据结构和工具的数据分析包
类似于 Numpy 的核心是 ndarray,pandas 也是围绕着 Series 和 DataFrame 两个核心数据结构展开的 。Series 和 DataFrame 分别对应于一维的序列和二维的表结构。pandas 约定俗成的导入方法如下:
预先加载:
from pandas import Series,DataFrame import pandas as pd
本图来源于:https://s3.amazonaws.com/assets.datacamp.com/blog_assets/PandasPythonForDataScience+(1).pdf
————————————————————————————————————-
一、Series 和 DataFrame构成
1、series构造
s = Series([1,2,3.0,'abc']) #object可以多格式,像list(c(1,2,3.0,'abc'));dtppe为单种格式 s = Series(data=[1,3,5,7],index = ['a','b','x','y']) #其中Index=rownames s.index #=R=rownames(s) s.values #=R=s s.name #colnames列名之上名字 s.index.name #rownames行名之上名字
python很看重index这个属性,相比之下R对于索引的操作明显要弱很多。在延伸中提到对索引的修改与操作。
2、dataframe构造
data = {'state':['Ohino','Ohino','Ohino','Nevada','Nevada'], 'year':[2000,2001,2002,2001,2002], 'pop':[1.5,1.7,3.6,2.4,2.9]}
大括号代表词典,有点像list,可以自定义数列的名字。
df=DataFrame(data)
其中DataFrame(data=None,index=None,columns=None)其中index代表行名称,columns代表列名称
其中df.index/df.columns分别代表行名称与列名称:
df.index #行名 df.columns #列名
其中index也是索引,而且不是那么好修改的。
————————————————————————————————————-
二、以某规则重排列.reindex
1、series
series.reindex(index,method,fill_values) s.reindex(index=[2,1,3,6]) #类似order重排列 此时,按照2,1,3的顺序重新排列 s.reindex(index=[2,1,3,6],fill_value=0) #fill_value插补方式,默认NaN,此时为0 s.reindex(index=[2,1,3,6],fill_value=0,method="backfill") #method:{'backfill', 'bfill', 'pad', 'ffill', None}(ffill = pad,bfill = back fill,分别指插值时向前还是向后取值)
2、dataframe
#dataframe索引,匹配,缺失值插补 dataframe.reindex(index,columns,method,fill_values) #插值方法 method 参数只能应用于行,即轴 0 state = ['Texas','Utha','California'] df.reindex(columns=state,method='ffill') #只能行插补 df.T.reindex(index=[1,6,3],fill_value=0).T #列插补技巧
————————————————————————————————————-
三、切片与删除、增加操作与选中
dataframe实质是numpy的高阶表现形式。如果选中也是很讲究,这个比R里面的dataframe要复杂一些:
两列:用irow/icol选中单个;用切片选择子集 .ix/.iloc
选择列:
#---1 利用名称选择列--------- data['w'] #选择表格中的'w'列,使用类字典属性,返回的是Series类型 data.w #选择表格中的'w'列,使用点属性,返回的是Series类型 data[['w']] #选择表格中的'w'列,返回的是DataFrame类型 data[['w','z']] #选择表格中的'w'、'z'列 #---2 利用序号寻找列--------- data.icol(0) #取data的第一列 data.ix[:,1] #返回第2行的第三种方法,返回的是DataFrame,跟data[1:2]同
利用序号选择的时候,注意[:,]中的:和,的用法
选择行:
#---------1 用名称选择----------------- data['a':'b'] #利用index值进行切片,返回的是**前闭后闭**的DataFrame, #即末端是包含的 data[0:2] #返回第1行到第2行的所有行,前闭后开,包括前不包括后 #--------跟data.table一样,可以不加逗号选中----------- data[1:2] #返回第2行,从0计,返回的是单行,通过有前后值的索引形式, #如果采用data[1]则报错 data.ix[1,:] #返回第2行的第三种方法,返回的是DataFrame,跟data[1:2]同 data.irow(0) #取data的第一行 data.iloc[-1] #选取DataFrame最后一行,返回的是Series data.iloc[-1:] #选取DataFrame最后一行,返回的是DataFrame
其中跟R中的data.table有点像的是,可以通过data[1],就是选中了第一行。
1、切片-定位
python的切片要是容易跟R进行混淆,那么现在觉得区别就是一般来说要多加一个冒号:
R中: data[1,] python中: data[1,:]
一开始不知道切片是什么,其实就是截取数据块。其中还有如何截取符合条件的数据列。
s[1:2] #x[2,2] df.ix[2,2] #df[3,3] df.ix[2:3,2:3] df.ix[2,"pop"] #可以用列名直接定位 df["pop"] df[:2] #横向第0行,第1行 df[df["pop"]>3] #df[df$pop>3]
跟R很大的区别,就是python中是从0开始算起。
同时定位的时候需要加入data.ix这个.ix很容易被忽略。
其中注意:
负向切片是需要仔细了解的:
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] >>> L[-2:] ['Bob', 'Jack'] >>> L[-2:-1] ['Bob']
2、删除
s.drop(1) #去掉index为1的行 df.drop(names,axis=0) #axis=0代表行,=1代表列;names代表列名(colnames)或者行名(rownames)
drop(colnames/rownames,axis=0/1)代表按行、按列删除。
3、增加
df.ix[5,:]=[3,"Nevada",3000]选中之后,填入数据,当然数值很多情况下,应该用合并的操作了。
————————————————————————————————————-
四、排序与排名
1、排序
foo.order(ascending=False) #按值,降序,ascending=True代表升序 foo.sort(ascending=False) #按index
也有两个,order和sort。其中sort_index是按照Index进行排列。
Series 的 sort_index(ascending=True) 方法可以对 index 进行排序操作,ascending 参数用于控制升序或降序,默认为升序。若要按值对 Series 进行排序,当使用 .order() 方法,任何缺失值默认都会被放到 Series 的末尾。在 DataFrame 上,.sort_index(axis=0, by=None, ascending=True) 方法多了一个轴向的选择参数与一个 by 参数,by 参数的作用是针对某一(些)列进行排序(不能对行使用 by 参数)。
df.sort(axis=0,ascending=False,by=None) #按index,比series 多了axis,横向纵向的功能 #by默认为None,by 参数的作用是针对某一(些)列进行排序(不能对行使用 by 参数) #by两个,df.sort_index(by=['California','Texas'])
dataframe的排序
2、排名rank
Series.rank(method='average', ascending=True) #返回的是名次的值value #处理平级项,方法里的 method 参数就是起这个作用的,他有四个值可选:average, min, max, first dataframe.rank(axis=0, method='first', ascending=True) #按行给出名次
排名(,ascending=False)
data.ix[:,1]代表选中第一列,然后sorted代表对第一列进行排序;
a.ix[:,1]-1 代表排好的秩,-1就还原到数据可以认识的索引。
————————————————————————————————————-
五、简单统计量/计数
df.mean(axis=0,skipna=True) =R=apply(df,mean,2) #df中的pop,按列求均值,skipna代表是否跳过均值
这个跟apply很像,返回的是按列求平均。其他常用的统计方法有:
######################## | ****************************************** |
count | 非 NA 值的数量 |
describe | 针对 Series 或 DF 的列计算汇总统计 |
min , max | 最小值和最大值 |
argmin , argmax | 最小值和最大值的索引位置(整数) |
idxmin , idxmax | 最小值和最大值的索引值 |
quantile | 样本分位数(0 到 1) |
sum | 求和 |
mean | 均值 |
median | 中位数 |
mad | 根据均值计算平均绝对离差 |
var | 方差 |
std | 标准差 |
skew | 样本值的偏度(三阶矩) |
kurt | 样本值的峰度(四阶矩) |
cumsum | 样本值的累计和 |
cummin , cummax | 样本值的累计最大值和累计最小值 |
cumprod | 样本值的累计积 |
diff | 计算一阶差分(对时间序列很有用) |
pct_change | 计算百分数变化 |
其中df.describe()还是挺有用的,对应R的summary:
1、频数统计
R中的table真的是一个逆天的函数,那么python里面有没有类似的函数呢?
data2=pd.DataFrame([1,2,3,4,1],index=["a","b","c","d","e"]);data2 data2[0].value_counts() Out[174]: 1 2 4 1 3 1 2 1 Name: 0, dtype: int64
还有交叉计数的情况,直接看效果:
df = pd.DataFrame({'A':['foo', 'bar', 'foo', 'bar','foo', 'bar', 'foo', 'foo'],'B':['one', 'one', 'two', 'three','two', 'two', 'one', 'three'],'C':np.arange(8),'D':np.arange(8,16)}) df Out[200]: A B C D 0 foo one 0 8 1 bar one 1 9 2 foo two 2 10 3 bar three 3 11 4 foo two 4 12 5 bar two 5 13 6 foo one 6 14 7 foo three 7 15
以上是数据:
df.groupby('A').sum()#按照A列的值分组求和 Out[202]: C D A bar 9 33 foo 19 59 df.groupby(['A','B']).sum()##按照A、B两列的值分组求和 Out[203]: C D A B bar one 1 9 three 3 11 two 5 13 foo one 6 22 three 7 15 two 6 22
还有分组计数:
groups['C'].count()##按照A列的值分组B组计数 Out[210]: A bar 3 foo 5 Name: C, dtype: int64
————————————————————————————————————-
六、缺失值处理
df.isnull #=R=is.na() df.dropna #去掉缺失值 df.fillna(value=None, method=None, axis=0) #填充方法,method df.notnull #跟isnull一样,=R=is.na()
————————————————————————————————————-
七、其他
1、组合相加
两个数列,返回的Index是两个数据列变量名称的;value中重复数据有值,不重复的没有。
#series dataframe的算术 foo = Series({'a':1,'b':2}) bar = Series({'b':3,'d':4}) foo+bar #merge(foo,bar,by=index)匹配到的数字相加,未匹配到的用NaN表示2、dataframe应用函数
#函数——apply族的用法 f = lambda x:x.max()-x.min() #numpy的附函数 df.apply(f) #.apply(func,axis=0,args,kwds)默认为axis=0情况下按列操作函数f3、inplace 用法
DataFrame(data,inplace=False)
Series 和 DataFrame 对象的方法中,凡是会对数组作出修改并返回一个新数组的,往往都有一个 replace=False 的可选参数。如果手动设定为 True,那么原数组就可以被替换。
4、DataFrame转换为其他类型
df.to_dict(outtype='dict')
outtype的参数为‘dict’、‘list’、‘series’和‘records’。 dict返回的是dict of dict;list返回的是列表的字典;series返回的是序列的字典;records返回的是字典的列表:
data2=pd.DataFrame([1,2,3,4],index=["a","b","c","d"]) data2.to_dict(outtype='dict') Out[139]: {0: {'a': 1, 'b': 2, 'c': 3, 'd': 4}} data2.to_dict(outtype='list') Out[140]: {0: [1, 2, 3, 4]} data2.to_dict(outtype='series') Out[141]: {0: a 1 b 2 c 3 d 4 Name: 0, dtype: int64} data2.to_dict(outtype='records') Out[142]: [{0: 1}, {0: 2}, {0: 3}, {0: 4}]
单列数据转化类型,用astype函数:
data2=pd.DataFrame([1,2,3,4],index=["a","b","c","d"]) type(data2[0]) data2[0].astype(float) Out[155]: a 1.0 b 2.0 c 3.0 d 4.0 Name: 0, dtype: float64
5、pandas中字符处理
pandas提供许多向量化的字符操作,你可以在str属性中找到它们
s.str.lower() s.str.len() s.str.contains(pattern)
6、时间序列
时间序列也是Pandas的一个特色。时间序列在Pandas中就是以Timestamp为索引的Series。
pandas提供to_datetime方法将代表时间的字符转化为Timestamp对象:
s = '2013-09-16 21:00:00'
ts = pd.to_datetime(s)
有时我们需要处理时区问题:
ts=pd.to_datetime(s,utc=True).tz_convert('Asia/Shanghai')
构建一个时间序列:
rng = pd.date_range('1/1/2012', periods=5, freq='M')
ts = pd.Series(randn(len(rng)), index=rng)
Pandas提供resample方法对时间序列的时间粒度进行调整:
ts_h=ts.resample('H', how='count')#M,5Min,1s
以上是将时间序列调整为小时,还可以支持月(M),分钟(Min)甚至秒(s)等。
参考博客:《Python中的结构化数据分析利器-Pandas简介》
————————————————————————————————————-
延伸应用一:dataframe如何横向、纵向合并?
1、横向合并,跟R一样,用merge就可以。
merge(data1,data2,on="id",, how='left'/'right')
merge(data1,data2,left_on='id1', right_on='id2', how='left'/'right') #如果两个数据集Key不一样,也可以合并
D1 = pd.DataFrame({'id':[801, 802, 803,804, 805, 806, 807, 808, 809, 810], 'name':['Ansel', 'Wang', 'Jessica', 'Sak','Liu', 'John', 'TT','Walter','Andrew','Song']}) D2 = pd.DataFrame({'id':[803, 804, 808,901], 'save': [3000, 500, 1200, 8800]}) merge(D1, D2, on='id')
2、纵向合并、堆砌——concat
concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)
concat不会去重,要达到去重的效果可以使用drop_duplicates方法。
1、objs 就是需要连接的对象集合,一般是列表或字典;
2、axis=0 是连接轴向join='outer' 参数作用于当另一条轴的 index 不重叠的时候,只有 'inner' 和 'outer' 可选(顺带展示 ignore_index=True 的用法),axis=1,代表按照列的方式合并。
3、join_axes=[] 指定自定义索引
4、参数ignore_index=True 重建索引
同时,可以标识出来, keys=[ , ] 来标识出来,基本语句为:concat([D1,D2], keys=['D1', 'D2'] )
同时,concat也可以暴力的横向合并:concat([D1,D2], axis=1)
注意:
特别是参数ignore_index=True,一定要带上,因为不带上会出现索引都是0000,那么就不能方便地使用切片,而发生切片都是“0”
————————————————————————————————————-
延伸二:DataFrame横向合并/拼接 出现不可合并问题的
尤其是两个数据集需要横向合并的情况,索引一般会出现较大的问题。如果自定义了索引,自定的索引会自动寻找原来的索引,如果一样的,就取原来索引对应的值,这个可以简称为“自动对齐”。
那么这样的两列数:
data1=pd.Series([1,2,3,4],index=["a","b","c","d"]) data2=pd.Series([3,2,3,4],index=["e","f","g","h"]) pd.concat([pd.DataFrame(data1).T,pd.DataFrame(data2).T]) Out[11]: a b c d e f g h 0 1.0 2.0 3.0 4.0 NaN NaN NaN NaN 0 NaN NaN NaN NaN 3.0 2.0 3.0 4.0
那么由于索引不一样,就会出现合并起来的时候,不对齐。
这时候就需要对索引进行修改,以下就是纵向/横向修改:
data1.T.columns=["e","f","g","h"] data1.index=["e","f","g","h"]
只有索引修改完之后才能进行合并,不然就会出现文不对题的情况。
其中注意:
series没有转置的情况
series没有转置的情况,我在尝试Series之间的横向合并的时候,只能纵向拼接。所以,需要转化成dataframe格式才能进行纵向拼接。
data1=pd.Series([1,2,3,4],index=["a","b","c","d"]) data2=pd.Series([3,2,3,4],index=["e","f","g","h"]) pd.concat([data1.T,data2.T]) Out[31]: a 1 b 2 c 3 d 4 e 3 f 2 g 3 h 4 dtype: int64
————————————————————————————————————-
延伸三:dataframe、series的索引删除与创建问题
可以看到,延伸三里面提到了因为索引而不方便进行数据操作的问题。那么如何在pandas进行索引操作呢?索引的增加、删除。
创建的时候,你可以指定索引。譬如:
pd.DataFrame([1,2],index=("a","b"),columns=("c")) pd.Series([1,2],index=("a","b"))
从上面的内容,可以看出dataframe可以指定纵向、横向的索引。而series只能指定一个维度的索引。
(1)pd.DataFrame+pd.Series不能通过(index=None)来消除index:
所以,DataFrame/series也是不能通过以下的办法来取消索引:
data1=pd.Series([1,2,3,4],index=["a","b","c","d"]) pd.Series(data1,index=None) Out[44]: a 1 b 2 c 3 d 4 dtype: int64
以及
data2=pd.DataFrame([1,2,3,4],index=["a","b","c","d"]) pd.DataFrame(data2,index=None,columns=None) Out[45]: 0 a 1 b 2 c 3 d 4
(2)通过reset_index来消除index
DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill='') #inplace,是否删除原索引 #drop,删除原索引后,时候生成新的Index列
可以来看一下这个函数的效果:
data2=pd.DataFrame([1,2,3,4],index=["a","b","c","d"]) data2.reset_index(inplace=True,drop=False);data2 Out[125]: index 0 0 a 1 1 b 2 2 c 3 3 d 4
来看看开启inplace+关闭drop的效果,把Index列单独加入了数列中。
data2=pd.DataFrame([1,2,3,4],index=["a","b","c","d"]) data2.reset_index(inplace=True,drop=True);data2 Out[126]: 0 0 1 1 2 2 3 3 4
inplace开启+开启drop的效果,单独把index都删除了。
一句Python,一句R︱pandas模块——高级版data.frame的更多相关文章
- R 语言处理excel为data.frame
使用 R包 xlsx 或者 openxlsx 安装 install.packages("xlsx", repos="https://cloud.r-project.org ...
- 吴裕雄--天生自然python学习笔记:pandas模块强大的数据处理套件
用 Python 进行数据分析处理,其中最炫酷的就属 Pa ndas 套件了 . 比如,如果我 们通过 Requests 及 Beautifulsoup 来抓取网页中的表格数据 , 需要进行较复 杂的 ...
- python之pandas模块高级用法
一 agg,聚合,可以使用内置的函数 >>> import pandas as pd >>> import numpy as np >>> pp ...
- 吴裕雄--天生自然python学习笔记:pandas模块导入数据
有时候,手工生成 Pandas 的 DataFrame 数据是件非常麻烦的事情,所以我们通 常会先把数据保存在 Excel 或数据库中,然后再把数据导入 Pandas . 另 一种情况是抓 取网页中成 ...
- 吴裕雄--天生自然python学习笔记:pandas模块删除 DataFrame 数据
Pandas 通过 drop 函数删除 DataFrarne 数据,语法为: 例如,删除陈聪明(行标题)的成绩: import pandas as pd datas = [[65,92,78,83,7 ...
- 吴裕雄--天生自然python学习笔记:pandas模块DataFrame 数据的修改及排序
import pandas as pd datas = [[65,92,78,83,70], [90,72,76,93,56], [81,85,91,89,77], [79,53,47,94,80]] ...
- 吴裕雄--天生自然python学习笔记:pandas模块用 dataframe.loc 通过行、列标题读取数据
用 df.va lue s 读取数据的前提是必须知道学生及科目的位置,非常麻烦 . 而 df.loc 可直接通过行.列标题读取数据,使用起来更为方便 . 使用 df.loc 的语法为: 行标题或列标题 ...
- 吴裕雄--天生自然python学习笔记:pandas模块读取 Data Frame 数据
读取行数据 读取一个列数据的语法为: 例如,读取所有学生自然科目的成绩 : import pandas as pd datas = [[65,92,78,83,70], [90,72,76,93,56 ...
- R vs Python:构建data.frame、读取csv与统计描述
一.Python 数据框就是典型的关系型数据库的数据存储形式,每一行是一条记录,每一列是一个属性,最终构成表格的形式,这是数据科学家必须熟悉的最典型的数据结构. 1.构建数据框 import pand ...
随机推荐
- Unity Android 5.6版本Resources.Load效率的问题
0x00 前言 相信不少使用Unity的小伙伴都听说过,甚至也亲身经历过在Unity5.6最初的几个版本中使用Resources.Load方法加载资源变--慢的问题. 这个问题的确是存在的,比如这个i ...
- mysql修改root用户密码
自我总结,欢迎拍砖! 目的:若root用户密码忘记,则需要重新设置root用户的密码. 步骤: 1.找到mysql安装目录下的 my.ini 文件,找到[mysqlId]一行,在下方添加语句:skip ...
- iOS-键盘监听YYKeyboardManager
如果键盘弹出覆盖了原有的试图,这种效果并不好,所以我们就要在键盘弹出的时候,监听键盘的位置来改变我们一些试图的位置,例如tableView列表等:在这里推荐一个大牛ibireme写的YYKeyboar ...
- BZOJ 3731 3731: Gty的超级妹子树 [树上size分块 !]
传送门 题意:一棵树,询问子树中权值大于k的节点个数,修改点权值,插入新点,断开边:强制在线 该死该死该死!!!!!! MD我想早睡觉你知不知道 该死该死沙比提 断开边只会影响一个块,重构这个块就行了 ...
- BZOJ 1935: [Shoi2007]Tree 园丁的烦恼 [树状数组 离线 离散化]
传送门 刚才我还在郁闷网上怎么没人用$CDQ$分治做 突然发现根本没有时间序.... #include<iostream> #include<cstdio> #include& ...
- Python tutorial阅读之函数的定义与使用
函数的定义 Python 使用关键字def定义函数,格式与C语言类似,但是没有返回类型,参数也不需要设置类型. def add(a, b): """这是函数的文档字符串& ...
- 云计算之路-阿里云上:重启 manager 节点引发 docker swarm 集群宕机
为了迎接春节假期后的访问高峰,我们今天对 docker swarm 集群进行了变更操作,购买了1台阿里云4核8G的服务器作为 worker 节点,由原来的 3 manager nodes + 2 w ...
- qt事件机制---事件范例
在笔记qt课程04笔记中
- qt中的事件机制
事件 1.QEvent -->类型 -> QKeyEvent QEvent::KeyRelease QEvent::MouseMove -> QMouseEvent 2.事件处理过程 ...
- shiro权限控制的简单实现
权限控制常用的有shiro.spring security,两者相比较,各有优缺点,此篇文章以shiro为例,实现系统的权限控制. 一.数据库的设计 简单的五张表,用户.角色.权限及关联表: CREA ...