Python pandas

在Python中,pandas是基于NumPy数组构建的,使数据预处理、清洗、分析工作变得更快更简单。pandas是专门为处理表格和混杂数据设计的,而NumPy更适合处理统一的数值数组数据。
使用下面格式约定,引入pandas包:

import pandas as pd

pandas有两个主要数据结构:Series和DataFrame。

Series

Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成,即index和values两部分,可以通过索引的方式选取Series中的单个或一组值。

Series的创建

pd.Series(list,index=[ ]),第二个参数是Series中数据的索引,可以省略。

  • 第一个参数可以是列表\ndarray
import numpy as np, pandas as pd
arr1 = np.arange(10)
s1 = pd.Series(arr1)
print(s1)   #由于我们没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的长度)的整数型索引
0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9

  • 第一个参数可以是字典,字典的键将作为Series的索引
  • 第一个参数可以是DataFrame中的某一行或某一列

Series类型的操作

Series类型索引、切片、运算的操作类似于ndarray,同样的类似Python字典类型的操作,包括保留字in操作、使用.get()方法。
Series和ndarray之间的主要区别在于Series之间的操作会根据索引自动对齐数据。

DataFrame

DataFrame是一个表格型的数据类型,每列值类型可以不同,是最常用的pandas对象。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)。DataFrame中的数据是以一个或多个二维块存放的(而不是列表、字典或别的一维数据结构)。

DataFrame的创建

pd.DataFrame(data,columns = [ ],index = [ ]):columns和index为指定的列、行索引,并按照顺序排列。

  • 创建DataFrame最常用的是直接传入一个由等长列表或NumPy数组组成的字典,会自动加上行索引,字典的会被当做列索引
import pandas as pd
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002, 2003],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
df= pd.DataFrame(data)
In [45]: df
Out[45]: 
   pop   state  year
0  1.5    Ohio  2000
1  1.7    Ohio  2001
2  3.6    Ohio  2002
3  2.4  Nevada  2001
4  2.9  Nevada  2002
5  3.2  Nevada  2003

如果创建时指定了columns和index索引,则按照索引顺序排列,并且如果传入的列在数据中找不到,就会在结果中产生缺失值:

In [48]: df2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
   ....:                       index=['one', 'two', 'three', 'four', 'five', 'six'])
In [49]: df2
Out[49]: 
       year   state  pop debt
one    2000    Ohio  1.5  NaN
two    2001    Ohio  1.7  NaN
three  2002    Ohio  3.6  NaN
four   2001  Nevada  2.4  NaN
five   2002  Nevada  2.9  NaN
six    2003  Nevada  3.2  NaN

  • 另一种常见的创建DataFrame方式是使用嵌套字典,如果嵌套字典传给DataFrame,pandas就会被解释为外层字典的键作为列,内层字典键则作为行索引:
In [65]: pop = {'Nevada': {2001: 2.4, 2002: 2.9},
....:        'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
In [66]: df3 = pd.DataFrame(pop)
In [67]: df3
Out[67]: 
      Nevada  Ohio
2000     NaN   1.5
2001     2.4   1.7
2002     2.9   3.6

image

DataFrame对象操作

  • df.values:将DataFrame转换为ndarray二维数组,注意后面不加()。
  • 通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series。
  • 列可以通过赋值的方式进行修改。例如,我们可以给那个空的"debt"列赋上一个标量值或一组值。
  • 将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值。
  • 为不存在的列赋值会创建出一个新列。关键字del用于删除列。
import pandas as pd
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002, 2003],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
In [48]: df2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
   ....:                       index=['one', 'two', 'three', 'four', 'five', 'six'])

In [50]: df2.columns
Out[50]: Index(['year', 'state', 'pop', 'debt'], dtype='object')
#通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series。
In [51]: df2['state']  #或者df2.state
Out[51]: 
one        Ohio
two        Ohio
three      Ohio
four     Nevada
five     Nevada
six      Nevada
Name: state, dtype: object
#列可以通过赋值的方式进行修改。例如,我们可以给那个空的"debt"列赋上一个标量值或一组值
In [54]: frame2['debt'] = 16.5
In [55]: frame2
Out[55]: 
       year   state  pop  debt
one    2000    Ohio  1.5  16.5
two    2001    Ohio  1.7  16.5
three  2002    Ohio  3.6  16.5
four   2001  Nevada  2.4  16.5
five   2002  Nevada  2.9  16.5
six    2003  Nevada  3.2  16.5
#将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值
In [58]: val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
In [59]: df2['debt'] = val
In [60]: df2
Out[60]: 
       year   state  pop  debt
one    2000    Ohio  1.5   16.5
two    2001    Ohio  1.7  -1.2
three  2002    Ohio  3.6   16.5
four   2001  Nevada  2.4  -1.5
five   2002  Nevada  2.9  -1.7
six    2003  Nevada  3.2   16.5
#为不存在的列赋值,会创建出一个新列
In [61]: df2['eastern'] = df2.state == 'Ohio'
In [62]: df2
Out[62]: 
       year   state  pop  debt  eastern
one    2000    Ohio  1.5   NaN     True
two    2001    Ohio  1.7  -1.2     True
three  2002    Ohio  3.6   NaN     True
four   2001  Nevada  2.4  -1.5    False
five   2002  Nevada  2.9  -1.7    False
six    2003  Nevada  3.2   NaN    False
#关键字del用于删除列
In [63]: del df2['eastern']
In [64]: df2.columns
Out[64]: Index(['year', 'state', 'pop', 'debt'], dtype='object')

pandas的基本功能

数据索引:Series和DataFrame的索引是Index类型,Index对象是不可修改,可通过索引值或索引标签获取目标数据,也可通过索引使序列或数据框的计算、操作实现自动化对齐。索引类型index的常用方法:

  • .append(idx):连接另一个Index对象,产生新的Index对象

  • .diff(idx):计算差集,产生新的Index对象

  • .intersection(idx):计算交集

  • .union(idx):计算并集

  • .delete(loc):删除loc位置处的元素

  • .insert(loc,e):在loc位置增加一个元素

    image
    image
    image

重新索引:能够改变、重排Series和DataFrame索引,会创建一个新对象,如果某个索引值当前不存在,就引入缺失值。
df.reindex(index, columns ,fill_value, method, limit, copy ):index/columns为新的行列自定义索引;fill_value为用于填充缺失位置的值;method为填充方法,ffill当前值向前填充,bfill向后填充;limit为最大填充量;copy 默认True,生成新的对象,False时,新旧相等不复制。

In [98]: frame = pd.DataFrame(np.arange(9).reshape((3, 3)),
   ....:                      index=['a', 'c', 'd'],columns=['Ohio', 'Texas', 'California'])
In [99]: frame
Out[99]: 
   Ohio  Texas  California
a     0      1           2
c     3      4           5
d     6      7           8

In [100]: frame2 = frame.reindex(['a', 'b', 'c', 'd'])
In [101]: frame2
Out[101]: 
   Ohio  Texas  California
a   0.0    1.0         2.0
b   NaN    NaN         NaN
c   3.0    4.0         5.0
d   6.0    7.0         8.0

删除指定索引:默认返回的是一个新对象。
.drop():能够删除Series和DataFrame指定行或列索引。
删除一行或者一列时,用单引号指定索引,删除多行时用列表指定索引。
如果删除的是列索引,需要增加axis=1或axis='columns'作为参数。
增加inplace=True作为参数,可以就地修改对象,不会返回新的对象。

image

索引、选取和过滤
df.loc[行标签,列标签]:通过标签查询指定的数据,第一个值为行标签,第二值为列标签。当第二个参数为空时,查询的是单个或多个行的所有列。如果查询多个行、列的话,则两个参数用列表表示。
df.iloc[行位置,列位置]:通过默认生成的数字索引查询指定的数据。

In [128]: data = pd.DataFrame(np.arange(16).reshape((4, 4)),
   .....:                     index=['Ohio', 'Colorado', 'Utah', 'New York'],
   .....:                     columns=['one', 'two', 'three', 'four'])
​
In [129]: data
Out[129]: 
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
#df.loc选取第二行、第二三列
In [137]: data.loc['Colorado', ['two', 'three']]   
Out[137]: 
two      5
three    6
Name: Colorado, dtype: int64
#df.iloc选取第二行、第二三列
In [138]: data.iloc[1, [1, 2]]
Out[138]: 
two      5
three    6
Name: Colorado, dtype: int64

在pandas中,有多个方法可以选取和重新组合数据。对于DataFrame,表5-4进行了总结

image

算术运算:算术运算根据行列索引,对齐后运算,运算默认产生浮点数,对齐时缺项填充NaN (空值)。除了用+-*/外,还可以用Series和DataFrame的算术方法,这些方法传入fill_value参数时,可以填充缺省值。比如df1.add(df2, fill_value = 1):

image

比较运算只能比较相同索引的元素,不进行补齐。采用>< >= <= == !=等符号进行的比较运算,产生布尔值。
排序 :在排序时,任何缺失值默认都会被放到末尾
.sort_index(axis=0, ascending=True):根据指定轴索引的值进行排序。默认轴axis=0, ascending=True,即默认根据0轴的索引值做升序排序。轴axis=1为根据1轴的索引值排序, ascending=False为降序。
在指定轴上根据数值进行排序,默认升序。
Series.sort_values(axis=0, ascending=True):只能根据0轴的值排序。
DataFrame.sort_values(by, axis=0, ascending=True),参数by为axis轴上的某个索引或索引列表。

pandas数据分析

统计分析、相关分析

适用于Series和DataFrame的基本统计分析函数:传入axis='columns'或axis=1将会按行进行运算。
.describe():针对各列的多个统计汇总,用统计学指标快速描述数据的概要。
.sum():计算各列数据的和
.count():非NaN值的数量
.mean( )/.median():计算数据的算术平均值、算术中位数
.var()/.std():计算数据的方差、标准差
.corr()/.cov():计算相关系数矩阵、协方差矩阵,是通过参数对计算出来的。Series的corr方法用于计算两个Series中重叠的、非NA的、按索引对齐的值的相关系数。DataFrame的corr和cov方法将以DataFrame的形式分别返回完整的相关系数或协方差矩阵。
.corrwith():利用DataFrame的corrwith方法,可以计算其列或行跟另一个Series或DataFrame之间的相关系数。传入一个Series将会返回一个相关系数值Series(针对各列进行计算),传入一个DataFrame则会计算按列名配对的相关系数。
.min()/.max():计算数据的最小值、最大值
.diff():计算一阶差分,对时间序列很有效
.mode():计算众数,返回频数最高的那(几)个
.mean():计算均值
.quantile():计算分位数(0到1)
.isin():用于判断矢量化集合的成员资格,可用于过滤Series中或DataFrame列中数据的子集
适用于Series的基本统计分析函数,DataFrame[列名]返回的是一个Series类型。
.unique():返回一个Series中的唯一值组成的数组。
.value_counts():计算一个Series中各值出现的频率。
.argmin()/.argmax():计算数据最大值、最小值所在位置的索引位置(自动索引)
.idxmin()/.idxmax():计算数据最大值、最小值所在位置的索引(自定义索引)

分组

pandas读写文本格式的数据

pandas提供了一些用于将表格型数据读取为DataFrame对象的函数。下表对它们进行了总结,其中read_csv()、read_table()、to_csv()是用得最多的。

image

工作中实际碰到的数据可能十分混乱,一些数据加载函数(尤其是read_csv)的参数非常多(read_csv有超过50个参数)。具体使用参考https://seancheney.gitbook.io/python-for-data-analysis-2nd/di-06-zhang-shu-ju-jia-zai-cun-chu-yu-wen-jian-ge-shi

用pandas来进行数据清洗和准备

在数据分析和建模的过程中,相当多的时间要用在数据准备上:加载、清理、转换以及重塑。

处理缺失数据

在许多数据分析工作中,缺失数据是经常发生的。对于数值数据,pandas使用浮点值NaN(np.nan)表示缺失数据,也可将缺失值表示为NA(Python内置的None值)。

  • .info():查看数据的信息,包括每个字段的名称、非空数量、字段的数据类型。
  • .isnull():返回一个同样长度的值为布尔型的对象(Series或DataFrame),表示哪些值是缺失的,.notnull()为其否定形式。
import pandas as pd
import numpy as np
In [10]: string_data = pd.Series(['aardvark', 'artichoke', np.nan, None])
In [11]: string_data
Out[11]:
0     aardvark
1    artichoke
2          NaN
3         None
dtype: object

In [14]: string_data.isnull()
Out[14]: 
0    False
1    False
2     True
3     True
dtype: bool

  • .dropna():删除缺失数据。对于Series对象,dropna返回一个仅含非空数据和索引值的Series。对于DataFrame对象,dropna默认删除含有缺失值的行;如果想删除含有缺失值的列,需传入axis = 1作为参数;如果想删除全部为缺失值的行或者列,需传入how='all'作为参数;如果想留下一部分缺失数据,需传入thresh = n作为参数,表示每行至少n个非NA值。
import pandas as pd
import numpy as np
In [19]: data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA], [NA, 6.5, 3.]])
In [20]: data.dropna()
Out[22]: 
     0    1    2
0  1.0  6.5  3.0
#传入how='all'将只丢弃全为NA的那些行:
In [23]: data.dropna(how='all')
Out[23]: 
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
3  NaN  6.5  3.0

In [24]: data[4] = NA
In [25]: data
Out[25]: 
     0    1    2   4
0  1.0  6.5  3.0 NaN
1  1.0  NaN  NaN NaN
2  NaN  NaN  NaN NaN
3  NaN  6.5  3.0 NaN
#用这种方式丢弃列,只需传入axis=1即可:
In [26]: data.dropna(axis=1, how='all')
Out[26]: 
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0
#假设你只想留下一部分观测数据,可以用thresh参数实现此目的:
In [27]: df = pd.DataFrame(np.random.randn(7, 3))
In [28]: df.iloc[:4, 1] = NA
In [29]: df.iloc[:2, 2] = NA
In [30]: df
Out[30]: 
          0         1         2
0 -0.204708       NaN       NaN
1 -0.555730       NaN       NaN
2  0.092908       NaN  0.769023
3  1.246435       NaN -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741

In [32]: df.dropna(thresh=2)
Out[32]: 
          0         1         2
2  0.092908       NaN  0.769023
3  1.246435       NaN -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741

  • .fillna(value,method,limit,inplace):填充缺失值。value为用于填充的值(比如0、'a'等)或者是字典(比如{'列':1,'列':8,……}为指定列的缺失数据填充值);method默认值为ffill,向前填充,bfill为向后填充;limit为向前或者向后填充的最大填充量。inplace默认会返回新对象,修改为inplace=True可以对现有对象进行就地修改。

数据转换

替换值
.replace(old, new):用新的数据替换老的数据,如果希望一次性替换多个值,old和new可以是列表。默认会返回一个新的对象,传入inplace=True可以对现有对象进行就地修改。

删除重复数据

  • .duplicated():判断各行是否是重复行(前面出现过的行),返回一个布尔型Series。
  • .drop_duplicates():删除重复行,返回删除后的DataFrame对象。默认保留的是第一个出现的行,传入keep='last'作为参数后,则保留最后一个出现的行。
  • 两者都默认会对全部列做判断,在传入列索引组成的列表[ '列1' , '列2' , ……]作为参数后,可以只对这些列进行重复项判断。

利用函数或字典进行数据转换

  • Series.map():接受一个函数或字典作为参数。使用map方法是一种实现元素级转换以及其他数据清理工作的便捷方式。
import pandas as pd
In [52]: data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon','pastrami', 'corned beef', 'bacon','pastrami', 'honey ham', 'nova lox'],
   ....                       'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
meat_to_animal = {
  'bacon': 'pig',  'pulled pork': 'pig',  'pastrami': 'cow',  'corned beef': 'cow',
  'honey ham': 'pig',  'nova lox': 'salmon'
}
#增加一列animal
In [57]: data['animal'] = data['food'].map(meat_to_animal)
In [58]: data
Out[58]: 
          food  ounces  animal
0        bacon     4.0     pig
1  pulled pork     3.0     pig
2        bacon    12.0     pig
3     Pastrami     6.0     cow
4  corned beef     7.5     cow
5        Bacon     8.0     pig
6     pastrami     3.0     cow
7    honey ham     5.0     pig
8     nova lox     6.0  salmon

DataFrame常见函数

df.head():查询数据的前五行
df.tail():查询数据的末尾5行
pandas.cut()
pandas.qcut() 基于分位数的离散化函数。基于秩或基于样本分位数将变量离散化为等大小桶。
pandas.date_range() 返回一个时间索引
df.apply() 沿相应轴应用函数
Series.value_counts() 返回不同数据的计数值
df.aggregate()
df.reset_index() 重新设置index,参数drop = True时会丢弃原来的索引,设置新的从0开始的索引。常与groupby()一起用
numpy.zeros()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343