一句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 ...
随机推荐
- 图像映射<map>、<area>
1.<map>定义图像映射,图像映射(image-map)指带有可单击区域的一幅图像. 2.<area>定义图像映射中的区域,area元素永远嵌套在map元素内部,area元素 ...
- Hyperledger Fabric Endorsement policies——背书策略
背书策略 背书策略用于指导peer如何确定交易是否得到了的认可.当一个peer接收到一个事务时,它会调用与事务的Chaincode相关联的VSCC(验证系统链代码),作为事务验证流程的一部分,以确定交 ...
- shell中数组讲解
定义数组 在Shell中,用括号来表示数组,数组元素用"空格"符号分割开.定义数组的一般形式为: 代码如下: 数组名=(值1 值2 ... 值n) 例如: 代码如下: array_ ...
- linux shell 中的 2>&1 用法说明
linux中有三种标准输入输出,分别是 STDIN,STDOUT,STDERR,对应的数字是 0,1,2. STDIN 是标准输入,默认从键盘读取信息: STDOUT 是标准输出,默认将输出结果输出至 ...
- spring-boot 使用 main函数 无法启动的问题完美 解决方案。
首先 是启动之后 ,直接回exit code 0,网址 里面输入localhost:8080显示站点未启动.网上查 了多种 方式 ,日志 也 打了,都没发现问题,最后到这篇文章里 找到了答案.但是这 ...
- SpringMVC源码情操陶冶-ResourcesBeanDefinitionParser静态资源解析器
解析mvc:resources节点,控制对静态资源的映射访问 查看官方注释 /** * {@link org.springframework.beans.factory.xml.BeanDefinit ...
- RandomAccess接口的使用
RandomAccess在类Collections的shuffle()方法中的使用:(jdk源码如下) /** * Randomly permute the specified list using ...
- 扩展 KMP
扩展KMP解决这样一些问题: 给定两个字符串 S 和 T(长度分别为 n 和 m),下标从 0 开始,定义extend[i]等于S[i]...S[n-1]与 T 的最长相同前缀的长度,求出所有的ext ...
- asp.net core 使用html文件
在asp.net core 项目中,使用html文件一般通过使用中间件来提供服务: 打开 NuGet程序管理控制台 输入install-package Microsoft.aspnetcore.sta ...
- Asp.net core Razor 页面
创建asp.net core 空项目->MyWeb 修改Startup.cs启动文件添加Razor页面支持: public void ConfigureServices(IServiceColl ...