Pandas

家住魔仙堡 提交于 2020-02-26 13:35:56

Pandas简介

Pandas 是python的一个数据分析包,pandas是一款数据处理工具,集成了numpy以及matplotlib,拥有便捷的数据处理以及文件读取能力

Pandas 提供了三种数据对象,分别是 Series、 DataFrame 和 Panel。 其中 , Series 用于保存 一维类的数据, DataFrame 用于保存二维类的数据, Panel 用于保存三维类或者可变维度的数据。 在通常的数据分析中,我们经常使用 Series 和 DataFrame 这两种类型的数据,所以这两种类型 要重点介绍。

数据结构

Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。

Time- Series:以时间为索引的Series。

DataFrame:DataFrame是⼀个二维的表格型数据结构,它含有⼀组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有⾏索引也有列索引,它可以被看做由Series组成的字典(共⽤同⼀个索引)。DataFrame中的数据是以⼀个或多个⼆维块存放的(⽽不是列表、字典或别的⼀维数据结构)。

Panel :三维的数组,可以理解为DataFrame的容器。

Pandas 有两种自己独有的基本数据结构。读者应该注意的是,它固然有着两种数据结构,因为它依然是 Python 的一个库,所以,Python 中有的数据类型在这里依然适用,也同样还可以使用类自己定义数据类型。只不过,Pandas 里面又定义了两种数据类型:Series 和 DataFrame,它们让数据操作更简单了。

Series 对象

可理解为带索引的一维数组

创建 Series 对象

创建 Series 对象就是建立 Series 类的实例,其完整的参数列表是:

pd.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False) 
  • data: 可以是数组、列表等类数组对象,也可以是字典,还可以是一个数字、字符串 。
  • index: Series 对象的索引,如果为 None,则按照默认的从 0 开始的整数进行索引 。注 意 index 值的长度和 data 值的长度应该相同。
import numpy as np
import pandas as pd

g = np.array([27466.15, 24899.3, 19610.9, 19492.4, 17885.39, 17558.76, 15475.09, 12179.2])
print(g)

gdp = pd.Series(g, index=['shanghai', 'beijing', 'guangzhou', 'shenzhen', 'tianjin','chongqing', 'suzhou', 'chengdu'])
print(gdp)
输出:
[27466.15 24899.3  19610.9  19492.4  17885.39 17558.76 15475.09 12179.2 ]
shanghai     27466.15
beijing      24899.30
guangzhou    19610.90
shenzhen     19492.40
tianjin      17885.39
chongqing    17558.76
suzhou       15475.09
chengdu      12179.20
dtype: float64
a = pd.Series(data=[100, 200, 300])
print(a)
输出:
0    100
1    200
2    300
dtype: int64
a = pd.Series(100, index=['a', 'b', 'c'])
print(a)
输出:
a    100
b    100
c    100
dtype: int64
a = pd.Series({'wuhan':11912.6, 'hangzhou':11050.5, 'nanjing':10503})
print(a)
print('*********************')
a = pd.Series({'wuhan':11912.6, 'hangzhou':11050.5, 'nanjing':10503}, index=['nanjing','wuhan','hangzhou'])
print(a)
输出:
wuhan       11912.6
hangzhou    11050.5
nanjing     10503.0
dtype: float64
*********************
nanjing     10503.0
wuhan       11912.6
hangzhou    11050.5
dtype: float64

Series 对象属性

对于每个 Series 对象,都有 index 和 values 两个基本属性,可以分别获得标签索引和元素。

  • index—— 索引项
  • values——索引值,numpy.ndarray类型
a = pd.Series({'wuhan':11912.6, 'hangzhou':11050.5, 'nanjing':10503})
print(a)
print(a.index)
print(a.values)
输出:
wuhan       11912.6
hangzhou    11050.5
nanjing     10503.0
dtype: float64
Index(['wuhan', 'hangzhou', 'nanjing'], dtype='object')
[11912.6 11050.5 10503. ]

DataFrame

numpy仅用作计算,在数据表示方面还有所欠缺,很难从数据上面看出信息表达的含义,在这里我们可以将DataFrame看作是有行列索引(标题)的二维数组

Series 对象用于存储一维数据, DataFrame 专门用于存储二维数据。

创建 DataFrame 对象

在 Pandas 中,通过实例化 pd.DataFrame()创建 DataFrame 对象

pd.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False) 
  • data:可以是嵌套列表、 二维数组、字典或者 DataFrame 对象。字典中的数据除字符串、 数字等基本的 Python 数据类型外,还可以包括 Series、 数组等序列类型的对象。
  • index: 可以是索引对象或者类数组对象。当然,跟 Series 类似,如果 index 为 None, 则按照默认的 0、 l 、 2……顺序建立索引。
  • columns: 可以是索引对象或者类数组对象。其含义是列 索引 。 如果用数据库或者电子表格中的术语,则可以叫作“字段”。

下面就通过示例从不同侧面理解创建 DataFrame 对象的基本方法

import pandas as pd

gp = pd.DataFrame([[27466.15, 2419.70], [24899.30, 2172.90],
                    [19610.90, 1350.11], [19492.60, 1137.87],
                    [17885.39, 1562.12], [17558.76, 3016.55],
                    [15475.09, 1375.00], [12170.20, 1591.76]])
print(gp)
输出:
          0        1
0  27466.15  2419.70
1  24899.30  2172.90
2  19610.90  1350.11
3  19492.60  1137.87
4  17885.39  1562.12
5  17558.76  3016.55
6  15475.09  1375.00
7  12170.20  1591.76

没有向 index 和 columns 两个参数传入值,就用从 0 开始 计数的整数表示相应索引 。

与 Series 对象类似, 也能够通过 DataFrame 对象的 index 和 columns 两个属性为其设置 “标签索引”。

import pandas as pd
gp = pd.DataFrame([[27466.15, 2419.70], [24899.30, 2172.90],
                    [19610.90, 1350.11], [19492.60, 1137.87],
                    [17885.39, 1562.12], [17558.76, 3016.55],
                    [15475.09, 1375.00], [12170.20, 1591.76]])
gp.index =['SHANGHAI','BEIJING ','GUANGZHOU', 'CHONGQING ','SUZHOU', 'CHENGDU', 'WH', 'HAH']
gp.columns =['GDP', 'Population']
print(gp)
输出:
                 GDP  Population
SHANGHAI    27466.15     2419.70
BEIJING     24899.30     2172.90
GUANGZHOU   19610.90     1350.11
CHONGQING   19492.60     1137.87
SUZHOU      17885.39     1562.12
CHENGDU     17558.76     3016.55
WH          15475.09     1375.00
HAH         12170.20     1591.76

如果在创建 DataFrame 对象的时候,给 index 和 columns 传入参数,则可以用如下方式。

import pandas as pd

gp = pd.DataFrame([[27466.15, 2419.70], [24899.30, 2172.90],
                    [19610.90, 1350.11], [19492.60, 1137.87],
                    [17885.39, 1562.12], [17558.76, 3016.55]],
                    index = ['SHANGHAI', 'BEIJING ', 'GUANGZHOU', 'CHONGQING ', 'SUZHOU', 'CHENGDU'],
                    columns=['GDP', 'Population']
                  )

print(gp)
输出:
                 GDP  Population
SHANGHAI    27466.15     2419.70
BEIJING     24899.30     2172.90
GUANGZHOU   19610.90     1350.11
CHONGQING   19492.60     1137.87
SUZHOU      17885.39     1562.12
CHENGDU     17558.76     3016.55

还有与 Series 对象类似的操作,可以分别给 index 和 columns 命名

import pandas as pd

gp = pd.DataFrame([[27466.15, 2419.70], [24899.30, 2172.90],
                    [19610.90, 1350.11], [19492.60, 1137.87],
                    [17885.39, 1562.12], [17558.76, 3016.55]],
                    index = ['SHANGHAI', 'BEIJING ', 'GUANGZHOU', 'CHONGQING ', 'SUZHOU', 'CHENGDU'],
                    columns=['GDP', 'Population']
                  )

gp.index.name = 'City_Name'
gp.columns.name ='Items'
print(gp)
输出:
Items            GDP  Population
City_Name                       
SHANGHAI    27466.15     2419.70
BEIJING     24899.30     2172.90
GUANGZHOU   19610.90     1350.11
CHONGQING   19492.60     1137.87
SUZHOU      17885.39     1562.12
CHENGDU     17558.76     3016.55

data 参数所引用的值除上面的嵌套列表(该列表可以转换为二维数组)外, 还可以是字典 类型的数据。

import pandas as pd

gp = pd.DataFrame ({'city':['beijing', 'beijing', 'hubei', 'shanghai'],
                'marks': [100, 96.91, 82.57, 82.47]},
                index=['PKU', 'Tsinghua','WHU','Fudan'])
print(gp)
输出:
              city   marks
PKU        beijing  100.00
Tsinghua   beijing   96.91
WHU          hubei   82.57
Fudan     shanghai   82.47

用于创建 DataFrame 对象的数据,也包括自定义类型的数组

import numpy as np
import pandas as pd

u = np.array ([('beijing', 100),('beijing', 96.91), ('hubei', 82.57), ('shanghai', 82.47)],
              dtype=[('city', '30S'),('marks', np.float)])
pg = pd.DataFrame(u, index=['PKU', 'Tsinghua', 'WHU', 'Fudan'])
print(pg)
输出:
                 city   marks
PKU        b'beijing'  100.00
Tsinghua   b'beijing'   96.91
WHU          b'hubei'   82.57
Fudan     b'shanghai'   82.47

索引对象

在 Pandas 中,索引是对象,不仅可以有一级,还可以有多级。 也正是因为多级索引的存在, 才能够将本来多维的数据结构转换为二维或者一维,即 DataFrame 对象或者 Series 对象。

它们 的索引一-Index 对象和 Multilndex 对象。

Index 对象

每个 Series 对象都有一个 index 属性,通过此属 性得到的就是 Index 对象。

import numpy as np
import pandas as pd

s = pd.Series(np.random.randn(5))
print(s)
print(s.index)
print(s.index[0])
输出:
0    1.215105
1   -0.882641
2   -0.535513
3    0.104735
4   -1.186051
dtype: float64
RangeIndex(start=0, stop=5, step=1)
0

在创建 Series 对象的时候,我们己经通过 index 属性修改其“标签索引”的内容。

s.index = ['a',  'b', 'c', 'd', 'e']
print(s)
输出:
a    1.215105
b   -0.882641
c   -0.535513
d    0.104735
e   -1.186051
dtype: float64

Python 中的对象都是通过类创建的,那 么 Index 对象能不能通过类创建呢?

pd.Index(data=None, dtype=None, copy=False, name=None, fastpath=False, tupleize_cols=True, **kwargs)
ind = pd.Index(['physics', 'python', 'math', 'english'])
s = pd.Series([100, 90, 80, 70], index=ind)
print(s)
输出:
physics    100
python      90
math        80
english     70
dtype: int64

Multilndex 对象

Pandas 里面提供了多种方法用于创建 Multilndex 对象,以及在 Series 对象和 DataFrame 对 象中应用它。

通过函数创建

通过实例化类创建

在数据中使用 MultiIndex 对象

import pandas as pd

gdp_index =[("shanghai", 2015), ('shanghai', 2016),
            ('beijing', 2015), ('beijing', 2016),
            ('guangzhou', 2015), ('guangzhou', 2016)]
gdp_mind = pd.MultiIndex.from_tuples(gdp_index)
gdp3 = pd.Series( [25300, 27466, 23000, 24899, 18100, 19611], index=gdp_mind)
print(gdp3)
输出:
shanghai   2015    25300
           2016    27466
beijing    2015    23000
           2016    24899
guangzhou  2015    18100
           2016    19611
dtype: int64

在 Pandas 中,还有专门实现上述转换的函数,可以实现 Series 类型的对象和 DataFrame 类 型的对象之间的互换。

aa = gdp3.unstack()
print(aa)
print('********')  
bb = aa.stack()  
print(bb)
输出:
            2015   2016
beijing    23000  24899
guangzhou  18100  19611
shanghai   25300  27466
*****************************
beijing    2015    23000
           2016    24899
guangzhou  2015    18100
           2016    19611
shanghai   2015    25300
           2016    27466
dtype: int64

数据索引和切片

Series 对象索引和切片的使用

import pandas as pd

g = np.array([27466.15, 24899.3, 19610.9, 19492.4])
gdp = pd.Series(g, index=['shanghai','beijing', 'guangzhou', 'shenzhen'])
print(gdp)
print('**********************')
#获取某一个索引的值
print(gdp['shanghai'])
#判断索引是否在数组中
print('shanghai' in gdp)
print('shanghai11' in gdp)
#获取所有的索引
print(gdp.keys())
#获取所有的索引和值
print(list(gdp.items()))

gdp['hangzhou'] = 11050.5 #增加一项
print('******************************')
#同时获取多个索引的值
print(gdp[['shanghai','beijing']])
print('*********')
print(gdp[gdp>20000])

# 对于 Series 对象,拥有了标签索引的同时,位置索引也没有失效,所以依然可以通过位置 索引获取元素,跟 NumPy 中的数组一样。
print('-----------------------')
print(gdp[2])
print('-----------------------')
print(gdp[2:5])
输出;
shanghai     27466.15
beijing      24899.30
guangzhou    19610.90
shenzhen     19492.40
dtype: float64
**********************
27466.15
True
False
Index(['shanghai', 'beijing', 'guangzhou', 'shenzhen'], dtype='object')
[('shanghai', 27466.15), ('beijing', 24899.3), ('guangzhou', 19610.9), ('shenzhen', 19492.4)]
******************************
shanghai    27466.15
beijing     24899.30
dtype: float64
*********
shanghai    27466.15
beijing     24899.30
dtype: float64
-----------------------
19610.9
-----------------------
guangzhou    19610.9
shenzhen     19492.4
hangzhou     11050.5
dtype: float64

当索引为整数的时候,标签索引和位置索引会引起混乱,所以:

  • 若使用位置索引读取某些值,提倡使用 series.iloc[ ]。

  • 若使用标签索引读取某些值,提倡使用 series.loc[ ]。

s = pd.Series(np.random.randn(4), index=[1, 3, 5, 7])
print(s)
print('***********')
#位置索引
print(s.iloc[1])
print('-------')
print(s.iloc[1:3])
print('*********')
#标签索引
print(s.loc[1])
print(s.loc[1:3])
输出:
1    0.700621
3   -1.900641
5   -0.584151
7    0.413870
dtype: float64
***********
-1.9006412182989636
-------
3   -1.900641
5   -0.584151
dtype: float64
*********
0.7006208932997835
1    0.700621
3   -1.900641
dtype: float64
import pandas as pd

gdp_index = [('shanghai', 2015), ('shanghai', 2016), ('beijing', 2015), ('beijing', 2016), ('guangzhou', 2015),
             ('guangzhou', 2016)]
gdp_mind = pd.MultiIndex.from_tuples(gdp_index)
gdp = pd.Series([25300, 27466, 23000, 24899, 18100, 19611], index=gdp_mind)
print('''*******gdp***********''')
print(gdp)
print('''*******gdp['shanghai']***********''')
print(gdp['shanghai'])
#标签索引
print('''*******gdp.loc['shanghai']***********''')
print(gdp.loc['shanghai'])
print('''*******gdp.loc['shanghai', 2016]***********''')
print(gdp.loc['shanghai', 2016])
print('''*******gdp.loc[:,2015]***********''')
print(gdp.loc[:,2015])

#位置索引
print('''*******gdp.iloc[1]***********''')
print(gdp.iloc[1])
print('''*******gdp.iloc[1:5]***********''')
print(gdp.iloc[1:5])
print('''*******gdp.iloc[[1, 3, 5]]***********''')
print(gdp.iloc[[1, 3, 5]])
输出:
*******gdp***********
shanghai   2015    25300
           2016    27466
beijing    2015    23000
           2016    24899
guangzhou  2015    18100
           2016    19611
dtype: int64
*******gdp['shanghai']***********
2015    25300
2016    27466
dtype: int64
*******gdp.loc['shanghai']***********
2015    25300
2016    27466
dtype: int64
*******gdp.loc['shanghai', 2016]***********
27466
*******gdp.loc[:,2015]***********
shanghai     25300
beijing      23000
guangzhou    18100
dtype: int64
*******gdp.iloc[1]***********
27466
*******gdp.iloc[1:5]***********
shanghai   2016    27466
beijing    2015    23000
           2016    24899
guangzhou  2015    18100
dtype: int64
*******gdp.iloc[[1, 3, 5]]***********
shanghai   2016    27466
beijing    2016    24899
guangzhou  2016    19611
dtype: int64

.iloc[]和 loc[]分别提供了两个途径,允许在索引上分别使用位置索引和标签索引,为我们 从 Series 对象中取值提供了多种途.

DataFrame 对象

DataFrame 是二维的 Pandas 数据, 可以在一定程度上类比二维数组.

import pandas as pd

population = pd. Series ([2415.27, 2151.6, 1270.08], index= ['shanghai','beijing', 'guangzhou'])
gdp =pd .Series( [27466, 24899, 19611], index=['shanghai','beijing','guangzhou'])
d = pd.DataFrame ({'gdp':gdp, 'pop':population})
print('''---------d-------------''')
print(d)

#DataFrame 对象是类二维数组,其实撇开索引,其元素就是一个二维数组。
print('''---------d.values-------------''')
print(d.values)

# 如果仅取某列数据,则可以根据列名称或者宇段名称直接获得。
print('''-------------d['pop']-------------------''')
print(d['pop'])


#如果要获得某些行的切片,则可以用下边多种方式,
print('''---------------d['shanghai':'beijing']---------------------''')
print(d['shanghai':'beijing'])
print('''--------------d.loc['shanghai':'beijing']--------------------''')
print(d.loc['shanghai':'beijing'])
print('''-------------d.iloc[1:]------------------''')
print(d.iloc[1:])

#灵活获取
print('''--------d.loc['shanghai', 'pop']----------''')
print(d.loc['shanghai', 'pop'])
print('''--------d.loc[:, 'pop']----------''')
print(d.loc[:, 'pop'])
输出:
---------d-------------
             gdp      pop
shanghai   27466  2415.27
beijing    24899  2151.60
guangzhou  19611  1270.08
---------d.values-------------
[[27466.    2415.27]
 [24899.    2151.6 ]
 [19611.    1270.08]]
-------------d['pop']-------------------
shanghai     2415.27
beijing      2151.60
guangzhou    1270.08
Name: pop, dtype: float64
---------------d['shanghai':'beijing']---------------------
            gdp      pop
shanghai  27466  2415.27
beijing   24899  2151.60
--------------d.loc['shanghai':'beijing']--------------------
            gdp      pop
shanghai  27466  2415.27
beijing   24899  2151.60
-------------d.iloc[1:]------------------
             gdp      pop
beijing    24899  2151.60
guangzhou  19611  1270.08
--------d.loc['shanghai', 'pop']----------
2415.27
--------d.loc[:, 'pop']----------
shanghai     2415.27
beijing      2151.60
guangzhou    1270.08
Name: pop, dtype: float64

文件读取与存储

pandas提供了⼀些⽤于将表格型数据读取为DataFrame对象的函数。其中read_csv和read_table可能会是你今后⽤得最多的。

csv操作 pandas.read_csv和pandas.read_table

读取csv

read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False,keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compression='infer', thousands=None, decimal=b'.', lineterminator=None, quotechar='"', quoting=0,escapechar=None, comment=None, encoding=None, dialect=None, tupleize_cols=None,error_bad_lines=True, warn_bad_lines=True, skipfooter=0, doublequote=True, delim_whitespace=False,low_memory=True, memory_map=False, float_precision=None)

read_table(...)
  • filepath_or_buffer:文件路径
  • sep 指定分隔符。如果不指定参数,则会尝试使用逗号分隔。
  • header 指定行数用来作为列名,数据开始行数。如果文件中没有列名,则默认为0,否则设置为None。
  • usecols:指定读取的列名,列表形式,用作筛选所需要的数据,也可以通过drop函数剔除数据
  • names:如果遇到直接就是数据的文件,需要通过names参数手动填入索引项
  • skipinitialspace 忽略分隔符后的空白
  • skiprows 需要忽略的行数(从文件开始处算起),或需要跳过的行号列表(从0开始)
  • nrows 需要读取的行数(从文件头开始算起)。

实例:

读取有标题的文件

#ex1.csv   文件内容
a,b,c,d,message
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
import pandas as pd
import numpy as np
df = pd.read_csv('./ex1.csv')
print(df)
print('''-----df.keys()---------''')  
print(df.keys())

输出:
   a   b   c   d message
0  1   2   3   4   hello
1  5   6   7   8   world
2  9  10  11  12     foo
-----df.keys()---------
Index(['a', 'b', 'c', 'd', 'message'], dtype='object')

还可以使⽤read_table,并指定分隔符

import pandas as pd
import numpy as np
df = pd.read_table('./ex1.csv',sep=',')
print(df)

输出:
   a   b   c   d message
0  1   2   3   4   hello
1  5   6   7   8   world
2  9  10  11  12     foo

读取没有标题的文件:

#文件内容
ex1.csv
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
#让pandas为其分配默认的列名
df = pd.read_csv('./ex1.csv', header=None)
print(df)

输出:
   0   1   2   3      4
0  1   2   3   4  hello
1  5   6   7   8  world
2  9  10  11  12    foo
#⾃⼰定义列名
names = ['a', 'b', 'c', 'd', 'message']  
df = pd.read_csv('./ex1.csv', names=names)
print(df)

输出:
   0   1   2   3      4
0  1   2   3   4  hello
1  5   6   7   8  world
2  9  10  11  12    foo

假设你希望将message列做成DataFrame的索引。你可以明确表 示要将该列放到索引4的位置上,也可以通过index_col参数指 定"message":

names = ['a', 'b', 'c', 'd', 'message']  
df = pd.read_csv('./ex1.csv', names=names,index_col=names[4])
print(df)

输出:
         a   b   c   d
message               
hello    1   2   3   4
world    5   6   7   8
foo      9  10  11  12

如果希望将多个列做成⼀个层次化索引,只需传⼊由列编号或列 名组成的列表即可

#文件内容
key1,key2,value1,value2
one,a,1,2
one,b,3,4
one,c,5,6
one,d,7,8
two,a,9,10
two,b,11,12
two,c,13,14
two,d,15,16
df = pd.read_csv('./ex1.csv', index_col=['key1', 'key2'])
print(df)
输出:
           value1  value2
key1 key2                
one  a          1       2
     b          3       4
     c          5       6
     d          7       8
two  a          9      10
     b         11      12
     c         13      14
     d         15      16

⽤skiprows跳过⽂件的指定⾏

# hey!
a,b,c,d,message
# just wanted to make things more difficult for you
# who reads CSV files with computers, anyway?
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
df = pd.read_csv('./ex1.csv', skiprows=[0, 2, 3])
print(df)
输出:
   a   b   c   d message
0  1   2   3   4   hello
1  5   6   7   8   world
2  9  10  11  12     foo

逐块读取⽂本⽂件

在处理很⼤的⽂件时,或找出⼤⽂件中的参数集以便于后续处理时,你可能只想读取⽂件的⼀⼩部分或逐块对⽂件进⾏迭代。

如果只想读取⼏⾏(避免读取整个⽂件),通过nrows进⾏指定即可:

df = pd.read_csv('./ex1.csv', nrows=2)
print(df)
输出:#输出0 ,1 行
   1   2   3   4  hello
0  5   6   7   8  world
1  9  10  11  12    foo

处理分隔符格式

⼤部分存储在磁盘上的表格型数据都能⽤pandas.read_table进⾏加载。然⽽,有时还是需要做⼀些⼿⼯处理。由于接收到含有畸形⾏的⽂件⽽使read_table出⽑病的情况并不少⻅

  • 对于任何单字符分隔符⽂件,可以直接使⽤Python内置的csv模块。将任意已打开的⽂件或⽂件型的对象传给csv.reader

  • 对这个reader进⾏迭代将会为每⾏产⽣⼀个元组(并移除了所有的引号)

  • CSV⽂件的形式有很多。只需定义csv.Dialect的⼀个⼦类即可定义出新格式(如专⻔的分隔符、字符串引⽤约定、⾏结束符等):

import csv

f = open('./ex1.csv')
reader = csv.reader(f, delimiter=',')
for line in reader:
    print(line)

输出:
['1', '2', '3', '4', 'hello']
['5', '6', '7', '8', 'world']
['9', '10', '11', '12', 'foo']
['1', '2', '3', '4', 'hello']
['5', '6', '7', '8', 'world']
['9', '10', '11', '12', 'foo']

写入csv

DataFrame.to_csv(path_or_buf=None, sep=',', columns=None, header=True, index=True, index_label=None,mode='w', encoding=None)
  • path_or_buf:文件路径
  • sep:分隔符
  • columns:要保存的列,列表形式
  • header:默认为True,是否写进列索引值
  • index:是否写进行索引值
  • mode:w为重写,a为追加
  • series和dataframe操作基本一致

HDF5操作

    HDF5的存储支持压缩,使用的方式是blosc,速度最快也是pandas默认支持的,可以提高磁盘利用率,节省空间的同时还支持跨平台,可以轻松迁移到hadoop上面,HDF5文件的读取和存储需要指定一个键,值为要存储的DataFrame,一个键对应一个DataFrame,也可以相当于是存储三维数据了

读取hdf5

    读取以及写入需要指定键,不同的键对应不同的DataFrame

pandas.read_hdf(path_or_buf, key=None, **kwargs)
  • key:读取的键
  • mode:打开文件的方式

写入hdf5文件

可以写入同一个hdf5文件当中,以不同的键区分开来

DataFrame.to_hdf(path_or_buf, key, kwargs)

JSON文件操作

读取

pandas.read_json(path_or_buf=None,orient=None,typ='frame',lines=False)
  • orient:指定格式,以下为参数值
    • split
    • records(最常用的格式,其他了解即可)
    • index
    • columns
    • values
  • lines:是否逐行读取,默认为False
  • typ:指定转换成的对象类型,series或者dataframe,默认为frame

写入

pandas.to_json(path_or_buf=None,orient=None,typ='frame',lines=False)

处理缺失数据

NumPy 中的缺失数据

a= np.array([1, None, 5, 7, 9])
b = np.array([1, 3, 5, 7, 9])
#因为 a 中有一个 None,所以对该数组元素类型进行判断的时候,
# 返回的是 objecto 如果对 数组 a 进行运算,肯定是要报锚的。

print(a.dtype)
print(b.dtype)
输出:
object
int32

NumPy 提供了另外一个表示空缺的数据 np.nan,才能够像一个数字那样参与各种运算。

c = np.array([1, np.nan, 5, 7, 9])
print(c.dtype)
print(7 + np.nan)
print(0 * np.nan)
print(c.sum())
print(np.nansum(c))
print(np.nanmean(c))
输出:
object
int32
float64
nan
nan
nan
22.0
5.5

Pandas 处理缺失数据

s = pd.Series([1, np.nan, 3, None, 7, 9])
print(s)
输出:
0    1.0
1    NaN
2    3.0
3    NaN
4    7.0
5    9.0
dtype: float64

尽管在创建 Series 对象的列表中有 None,但在最终的 Series 中却被转换为 NaN,这样就不 妨碍计算了,并且在计算时, Pandas 自动摒除了 NaN 数据。

import pandas as pd
import numpy as np

s = pd.Series([1, np.nan, 3, None, 7, 9])
print(s)
#求和
print('-------s.sum()----------')
print(s.sum())
#判断是否空
print('---------s.isnull()----------')
print(s.isnull())
print('----------s.notnull()-----------')
print(s.notnull())
#获取非空数据
print('-------s[s.notnull()]----------')
print(s[s.notnull()])
#删除所有 NaN 数据,并返回不含 NaN 的新对象
print('---------s.dropna()---------')
print(s.dropna())
输出:
0    1.0
1    NaN
2    3.0
3    NaN
4    7.0
5    9.0
dtype: float64
-------s.sum()----------
20.0
---------s.isnull()----------
0    False
1     True
2    False
3     True
4    False
5    False
dtype: bool
----------s.notnull()-----------
0     True
1    False
2     True
3    False
4     True
5     True
dtype: bool
-------s[s.notnull()]----------
0    1.0
2    3.0
4    7.0
5    9.0
dtype: float64
---------s.dropna()---------
0    1.0
2    3.0
4    7.0
5    9.0
dtype: float64

dropna()的作用是删除所有 NaN 数据,并返回不含 NaN 的新对象, 注意原有的对象没有受 到影响。对于 Series 对象比较好理解,如果是 DataFrame 对象, 应该怎样 “删除” 呢?是删除 行, 还是删除列?

df = pd.DataFrame([[1, 2, np.nan, 4], [5, None, 7, 8], [9, 10, 11, 12]])
print(df)
#dropna()的作用是删除所有 NaN 数据,并返回不含 NaN 的新对象
print('----------df.dropna()-----------------')
print(df.dropna())
print('-----------df.dropna(axis=l)--------------')
print(df.dropna(axis=1))
print('''---------df.dropna(axis= 'columns')-----------''')
print(df.dropna(axis= 'columns'))

#fillna()的作用是用某个值把数据中的 NaN 替换掉
print('''--------df.fillna(method='ffill')------------''')
print(df.fillna(method='ffill'))  # 根据前面的值替换 NaN
print('''--------df.fillna(method='bfill')----------''')
print(df.fillna(method='bfill')) ##根据后面的位替换 NaN
print('''------------df.fillna(method='ffill', axis=1)------------''')
print(df.fillna(method='ffill', axis=1))
输出:
   0     1     2   3
0  1   2.0   NaN   4
1  5   NaN   7.0   8
2  9  10.0  11.0  12
----------df.dropna()-----------------
   0     1     2   3
2  9  10.0  11.0  12
-----------df.dropna(axis=l)--------------
   0   3
0  1   4
1  5   8
2  9  12
---------df.dropna(axis= 'columns')-----------
   0   3
0  1   4
1  5   8
2  9  12
--------df.fillna(method='ffill')------------
   0     1     2   3
0  1   2.0   NaN   4
1  5   2.0   7.0   8
2  9  10.0  11.0  12
--------df.fillna(method='bfill')----------
   0     1     2   3
0  1   2.0   7.0   4
1  5  10.0   7.0   8
2  9  10.0  11.0  12
------------df.fillna(method='ffill', axis=1)------------
     0     1     2     3
0  1.0   2.0   2.0   4.0
1  5.0   5.0   7.0   8.0
2  9.0  10.0  11.0  12.0

规整数据

轴向连接

在 NumPy 中,有一个名为 np.concatenate()的函数, 这个函数通过对 axis 参数进行赋值,实 现沿着所设置的轴方向连接数组。 Pandas 也提供了一个类似的函数,不过其参数更丰富。

pd.concat(objs, axis=0, join=’outer ’, join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True) 
  • objs 参与连接的对象,是必需的, 不能省略(序列或 Series DataFrame、 Panel 、字典等对象 )

  • axis 指定沿着哪个轴的方向连接 (0或 1 默认为 0)

  • join 默认为 outero 其他轴上的索引是按照 outer (并集)还是 inner (交集)连接

  • join_axes 指定其他 n-1 条轴索引 , 不执行交集/并集操作。 比如对于 DataFrame 对象,当 axis=0 时, 若 join axes 是列表,则该列表的值就是 DataFrame 的列标签

  • ignore_index 默认为 False。如果为 True,就摒弃连接铀的索引,代之以 0, ., n 一 l 的整数,这是一种新的索引

  • keys 默认为 Noneo 用于设置多级索引

  • levels 默认为 None 指定用于多级索引的标签

  • names 默认为 None。多级索引的名称

  • verify _integrity 默认为 False。 如果为 True, 当检查到连接的轴有重复时,会发起异常

连接两个 Series 对象,其他参数都采用默认值, 默认连接方向是 0 轴方向

sl = pd.Series( [100, 200, 300], index=['a', 'b', 'c'])
s2 = pd.Series ([400, 500, 600], index=['d', 'e', 'f'])
print(pd.concat([sl, s2]))
输出:
a    100
b    200
c    300
d    400
e    500
f    600
dtype: int64

连接对象是 DataFrame 对象

df1 = pd.DataFrame([[110, 120, 130],[210, 220, 230], [310, 320, 330]])
df2 = pd.DataFrame([[11, 12, 13],[21, 22, 23], [31, 32, 33]])
print(pd.concat([df1, df2]))
输出:
     0    1    2
0  110  120  130
1  210  220  230
2  310  320  330
0   11   12   13
1   21   22   23
2   31   32   33

对象的结构不同

sl = pd.Series([100, 200, 300], index=['a', 'b', 'c'])
df1 = pd.DataFrame([[110, 120, 130],[210, 220, 230], [310, 320, 330]])
print(pd.concat([df1, sl]))
输出:
     0      1      2
0  110  120.0  130.0
1  210  220.0  230.0
2  310  320.0  330.0
a  100    NaN    NaN
b  200    NaN    NaN
c  300    NaN    NaN
sl = pd.Series([100, 200, 300], index=['a', 'b', 'c'])
df1 = pd.DataFrame([[110, 120, 130],[210, 220, 230], [310, 320, 330]])
print(pd.concat([df1, sl], keys=['df1', 's1']))
输出:
         0      1      2
df1 0  110  120.0  130.0
    1  210  220.0  230.0
    2  310  320.0  330.0
s1  a  100    NaN    NaN
    b  200    NaN    NaN
    c  300    NaN    NaN

要实现沿着1轴方向连接,设定参数 axis=1即可

df1 = pd.DataFrame([[110, 120, 130],[210, 220, 230], [310, 320, 330]])
df2 = pd.DataFrame([[11, 12, 13],[21, 22, 23], [31, 32, 33]])

print(pd.concat([df1, df2], axis=1))
输出:
     0    1    2   0   1   2
0  110  120  130  11  12  13
1  210  220  230  21  22  23
2  310  320  330  31  32  33
df1 = pd.DataFrame([[110, 120, 130],[210, 220, 230], [310, 320, 330]], index=['a', 'c', 'd'])
df2 = pd.DataFrame([[11, 12, 13],[21, 22, 23], [31, 32, 33]], index=['b', 'c', 'd'])
print('''-------pd.concat([df1, df2], axis=1, join='outer')----------''')
print(pd.concat([df1, df2], axis=1, join='outer'))
print('''----pd.concat([df1, df2], axis=1, join='inner')-----''')
print(pd.concat([df1, df2], axis=1, join='inner'))
输出:
-------pd.concat([df1, df2], axis=1, join='outer')----------
       0      1      2     0     1     2
a  110.0  120.0  130.0   NaN   NaN   NaN
c  210.0  220.0  230.0  21.0  22.0  23.0
d  310.0  320.0  330.0  31.0  32.0  33.0
b    NaN    NaN    NaN  11.0  12.0  13.0
----pd.concat([df1, df2], axis=1, join='inner')-----
     0    1    2   0   1   2
c  210  220  230  21  22  23
d  310  320  330  31  32  33


合并数据

pd.merge()此函数是针对 DataFrame 对象而言的,并且对其实 施的是“database-style join”(数据库风格合并)

pd.merge(left,right, how=’ inner ’, on=None, left_on=None ,right_on=None, left_index=False right_index=False, sort=False, suffixes=(’_x', '_y ' ), copy=True, indicator=False)
  • left/right Data Frame 进行合并的两个 DataFrame 对象
  • how 默认为’inner’。
    • left/right: 仅以 left/right 的 DataFrame 对象中所指定的列为健、以并集 (outer)的方式合并数据。
    • outer: 两个 DataFrame 对象指定键的并集
    • inner: 两个 DataFrame 对象指定键的交集
  • on 默认为 Noneo 用于合并的字段名称(列标签)。一般是两个 DaraFrame 所共的列,如果on=None, 且未指定合并的链,则以两个 DataFrame 对象列标签的交集为合并的键
  • left_ on/right_ on 默认为 None。 从 left/right 所引用的DataFrame 对象中选择记录(列标签)作为数据合并的键
  • left_index/light_index 默认为 False。 如果为 True,则以 left/right 所引用对象的索引为建合并数据
left_df = pd.DataFrame({'grade':['a','b', 'b', 'a', 'c' ,'c', 'd' ], 'ldata': range(7)})
right_df = pd.DataFrame({'grade':['a', 'b', 'c'], 'rdata': [30, 40, 50]})
print(left_df)
print(right_df)
print('''-----pd.merge(left_df,right_df)-----''')
print(pd.merge(left_df,right_df))
print('''-----pd.merge(left_df, right_df, on='grade', how='inner')----''')
print(pd.merge(left_df, right_df, on='grade', how='inner'))
输出:
  grade  ldata
0     a      0
1     b      1
2     b      2
3     a      3
4     c      4
5     c      5
6     d      6
  grade  rdata
0     a     30
1     b     40
2     c     50
-----pd.merge(left_df,right_df)-----
  grade  ldata  rdata
0     a      0     30
1     a      3     30
2     b      1     40
3     b      2     40
4     c      4     50
5     c      5     50
-----pd.merge(left_df, right_df, on='grade', how='inner')----
  grade  ldata  rdata
0     a      0     30
1     a      3     30
2     b      1     40
3     b      2     40
4     c      4     50
5     c      5     50

能够被指定为键的列也可 以是多个

ldf = pd.DataFrame({'keyl': ['K0', 'K0', 'Kl', 'K2'], 'key2': ['K0', 'Kl', 'K0', 'Kl'],
                    'A':['A0', 'Al', 'A2','A3'], 'B':['B0','Bl','B3', 'B3']})

rdf = pd.DataFrame({'keyl':['K0', 'Kl','Kl','K2'], 'key2': ['K0', 'K0', 'K0', 'K0'],
                   'C':['C0', 'C1','C2','C3'], 'D':['D0', 'Dl', 'D2','D3']})
print(ldf)
print(rdf)
print('''--pd.merge(ldf,rdf, on=['keyl', 'key2'], how='inner')---''')
print(pd.merge(ldf, rdf, on=['keyl', 'key2'], how='inner'))
print('''--pd.merge(ldf, rdf, on=['keyl', 'key2'], how='outer')---''')
print(pd.merge(ldf, rdf, on=['keyl', 'key2'], how='outer'))
print('''--pd.merge(ldf, rdf, on=['keyl', 'key2'], how='left')----''')
print(pd.merge(ldf, rdf, on=['keyl', 'key2'], how='left'))
print('''--pd.merge(ldf, rdf, on=['keyl', 'key2'], how='left', indicator=True)---''')
print(pd.merge(ldf, rdf, on=['keyl', 'key2'], how='left', indicator=True))
输出:
  keyl key2   A   B
0   K0   K0  A0  B0
1   K0   Kl  Al  Bl
2   Kl   K0  A2  B3
3   K2   Kl  A3  B3
  keyl key2   C   D
0   K0   K0  C0  D0
1   Kl   K0  C1  Dl
2   Kl   K0  C2  D2
3   K2   K0  C3  D3
--pd.merge(ldf,rdf, on=['keyl', 'key2'], how='inner')---
  keyl key2   A   B   C   D
0   K0   K0  A0  B0  C0  D0
1   Kl   K0  A2  B3  C1  Dl
2   Kl   K0  A2  B3  C2  D2
--pd.merge(ldf, rdf, on=['keyl', 'key2'], how='outer')---
  keyl key2    A    B    C    D
0   K0   K0   A0   B0   C0   D0
1   K0   Kl   Al   Bl  NaN  NaN
2   Kl   K0   A2   B3   C1   Dl
3   Kl   K0   A2   B3   C2   D2
4   K2   Kl   A3   B3  NaN  NaN
5   K2   K0  NaN  NaN   C3   D3
--pd.merge(ldf, rdf, on=['keyl', 'key2'], how='left')----
  keyl key2   A   B    C    D
0   K0   K0  A0  B0   C0   D0
1   K0   Kl  Al  Bl  NaN  NaN
2   Kl   K0  A2  B3   C1   Dl
3   Kl   K0  A2  B3   C2   D2
4   K2   Kl  A3  B3  NaN  NaN
--pd.merge(ldf, rdf, on=['keyl', 'key2'], how='left', indicator=True)---
  keyl key2   A   B    C    D     _merge
0   K0   K0  A0  B0   C0   D0       both
1   K0   Kl  Al  Bl  NaN  NaN  left_only
2   Kl   K0  A2  B3   C1   Dl       both
3   Kl   K0  A2  B3   C2   D2       both
4   K2   Kl  A3  B3  NaN  NaN  left_only

组合数据

np.where()函数,根据条件对 a 和 b 中的数据元素进行筛选, 最终得到根据 条件选择出来的新的数据一一这个数据不是合井和连接而成的,而是分别从 a 和 b 中取出部分 若干元素新生成的 Series 对象

a = pd.Series([np.nan, 2, 4, np.nan, 8, 10])
b = pd.Series([1, 2, np.nan, np.nan, 5, np.nan])
print('''--np.where(pd.isnull(b), a, b)---''')
print(np.where(pd.isnull(b), a, b))
print('''---b.combine_first(a)--''')
print(b.combine_first(a))
输出:
--np.where(pd.isnull(b), a, b)---
[ 1.  2.  4. nan  5. 10.]
---b.combine_first(a)--
0     1.0
1     2.0
2     4.0
3     NaN
4     5.0
5    10.0
dtype: float64

DataFrame 类的实例对象也有 combine_first()方法。


dfl = pd.DataFrame({'one':[11, 12, np.nan, 13, np.nan],'two':[np.nan, 22, 23, np.nan, 24]})
df2 = pd.DataFrame({'one':np.arange(6),'two':np.linspace(10, 100, 6), 'three': np.logspace(2, 3, 6)})
print(dfl)
print(df2)
print('''---dfl.combine_first(df2)----''')
#使用df2补充df1中的数据
print(dfl.combine_first(df2))
输出:
    one   two
0  11.0   NaN
1  12.0  22.0
2   NaN  23.0
3  13.0   NaN
4   NaN  24.0
   one    two        three
0    0   10.0   100.000000
1    1   28.0   158.489319
2    2   46.0   251.188643
3    3   64.0   398.107171
4    4   82.0   630.957344
5    5  100.0  1000.000000
---dfl.combine_first(df2)----
    one        three    two
0  11.0   100.000000   10.0
1  12.0   158.489319   22.0
2   2.0   251.188643   23.0
3  13.0   398.107171   64.0
4   4.0   630.957344   24.0
5   5.0  1000.000000  100.0

数据转换

行列转换

data= pd.DataFrame(np.arange(10).reshape(2, 5), index=['one', 'two'] , columns= ['a', 'b', 'c', 'd', 'e'])

print(data)
print('''---data.stack()----''')
print(data.stack())
print('''---data.stack().unstack()---''')
print(data.stack().unstack())
输出:
     a  b  c  d  e
one  0  1  2  3  4
two  5  6  7  8  9
---data.stack()----
one  a    0
     b    1
     c    2
     d    3
     e    4
two  a    5
     b    6
     c    7
     d    8
     e    9
dtype: int32
---data.stack().unstack()---
     a  b  c  d  e
one  0  1  2  3  4
two  5  6  7  8  9

透视表

在电子表格中,有一种叫做“透视表”的操作,可以根据数据再归类。在 Pandas 里面,也有一个“透视表”的函数,用来实现此功能。

students= pd.DataFrame({'class':['classl' , 'class2', 'classl' , 'class2' ],
                        'subject':['physics','python','math ','physics'],
                        'numbers': [ 28, 30, 20, 80]})
print(students)
print('''--------------------''')
print(students.pivot(index= 'class', columns='subject', values='numbers'))
输出:
    class  subject  numbers
0  classl  physics       28
1  class2   python       30
2  classl    math        20
3  class2  physics       80
--------------------
subject  math   physics  python
class                          
class2     NaN     80.0    30.0
classl    20.0     28.0     NaN

分组运算

简单的统计运算

dfl = pd.DataFrame({'one':[11, 12, 14, 13, 15],'two':[11, 22, 23, 12, 24]})
print(dfl)
print('''----dfl.sum()-----''')
#求和
print(dfl.sum())
print('''----dfl.mean()----''')
#平均值
print(dfl.mean())
print(dfl.mean(axis=1))
#中位数
print('''---dfl.median()----''')
print(dfl.median())
print('''dfl.describe()''')
print(dfl.describe())
输出:
   one  two
0   11   11
1   12   22
2   14   23
3   13   12
4   15   24
----dfl.sum()-----
one    65
two    92
dtype: int64
----dfl.mean()----
one    13.0
two    18.4
dtype: float64
0    11.0
1    17.0
2    18.5
3    12.5
4    19.5
dtype: float64
---dfl.median()----
one    13.0
two    22.0
dtype: float64
dfl.describe()
             one        two
count   5.000000   5.000000
mean   13.000000  18.400000
std     1.581139   6.348228
min    11.000000  11.000000
25%    12.000000  12.000000
50%    13.000000  22.000000
75%    14.000000  23.000000
max    15.000000  24.000000

分组运算

为了理解分组,还是先完整呈现 groupby()方法的参数列表。

df .groupby(by=None, axis=0, level=None, as_index=True, soue=True, goup_keys=True, squeeze=False, **kwargs)

其中,参数 by 用来指明为当前数据对象进行分组的依据, 即分组的键。能够作为键的数据 类型包括字符串和其他可法代对象、函数或其他表达对应关系的对象类型。

df = pd.DataFrame({'subject':['math', 'physics', 'english', 'math', 'physics', 'english'],
                   'score':[90, 80, 70, 95 , 85, 75]})
print(df)
print('''----df.groupby("subject").sum()---''')
print(df.groupby("subject").sum())
输出:
   subject  score
0     math     90
1  physics     80
2  english     70
3     math     95
4  physics     85
5  english     75
----df.groupby("subject").sum()---
         score
subject       
english    145
math       185
physics    165

分组对象的运算方法

import pandas as pd

df = pd.DataFrame({'subject':['math', 'physics', 'english', 'math', 'physics', 'english'],
                   'score':[90, 80, 70, 95 , 85, 75]})
df ['teacher'] = [ 'Netwon', 'Netwon', 'Pascal', 'Netwon', 'Pascal' , 'Pascal']
df ['rank'] = [4, 5, 2, 9, 7, 5]
print(df)

print (df.groupby('teacher')['score'].describe())
输出:
   score  subject teacher  rank
0     90     math  Netwon     4
1     80  physics  Netwon     5
2     70  english  Pascal     2
3     95     math  Netwon     9
4     85  physics  Pascal     7
5     75  english  Pascal     5
         count       mean       std   min   25%   50%   75%   max
teacher                                                          
Netwon     3.0  88.333333  7.637626  80.0  85.0  90.0  92.5  95.0
Pascal     3.0  76.666667  7.637626  70.0  72.5  75.0  80.0  85.0

Panda 为分组对象提供了 些专有方法, aggregate ()、 apply()、filter()、 transform (), 用于解决分组运算中个性化的计算要求。注意 它们都是分组对象的方法 即它们都以分组 对象为单位进行计 ,

aggregate () 函数的 作用是可以将若干个用于统计运算 函数聚合 一起。

df = pd.DataFrame({'subject':['math', 'physics', 'english', 'math', 'physics', 'english'],
                   'score':[90, 80, 70, 95 , 85, 75]})
df ['teacher'] = [ 'Netwon', 'Netwon', 'Pascal', 'Netwon', 'Pascal' , 'Pascal']
df ['rank'] = [4, 5, 2, 9, 7, 5]
print(df)
print ('''-----df.groupby('teacher')['score'].describe()------''')
print (df.groupby('teacher')['score'].describe())
print ('''----df.groupby ('teacher') .aggregate(['mean', 'std', 'max'])------''')
print (df.groupby ('teacher') .aggregate(['mean', 'std', 'max']))

#,如果 aggregate ()的 参数不是由多个函数对象组成的列 ,而是一个函数对象,那么
# 就与下面所示一样了。
print ('''---df.groupby ('teacher').aggregate(np.median)----''')
print (df.groupby ('teacher').aggregate(np.median))

#aggregate () 方法还能够对不同 的列进行不 同的运算,方法就是 典形式建立
# 列标签 函数对象的映射关系
print ('''---df.groupby('teacher').aggregate({'score':np.mean, 'rank':np.median})---''')
print (df.groupby('teacher').aggregate({'score':np.mean, 'rank':np.median}))
输出:
   score  subject teacher  rank
0     90     math  Netwon     4
1     80  physics  Netwon     5
2     70  english  Pascal     2
3     95     math  Netwon     9
4     85  physics  Pascal     7
5     75  english  Pascal     5
-----df.groupby('teacher')['score'].describe()------
         count       mean       std   min   25%   50%   75%   max
teacher                                                          
Netwon     3.0  88.333333  7.637626  80.0  85.0  90.0  92.5  95.0
Pascal     3.0  76.666667  7.637626  70.0  72.5  75.0  80.0  85.0
----df.groupby ('teacher') .aggregate(['mean', 'std', 'max'])------
             score                    rank              
              mean       std max      mean       std max
teacher                                                 
Netwon   88.333333  7.637626  95  6.000000  2.645751   9
Pascal   76.666667  7.637626  85  4.666667  2.516611   7
---df.groupby ('teacher').aggregate(np.median)----
         score  rank
teacher             
Netwon      90     5
Pascal      75     5
---df.groupby('teacher').aggregate({'score':np.mean, 'rank':np.median})---
             score  rank
teacher                 
Netwon   88.333333     5
Pascal   76.666667     5

filter() 筛选数据

df = pd.DataFrame({'subject':['math', 'physics', 'english', 'math', 'physics', 'english'],
                   'score':[90, 80, 70, 95 , 85, 75]})
df ['teacher'] = [ 'Netwon', 'Netwon', 'Pascal', 'Netwon', 'Pascal' , 'Pascal']
df ['rank'] = [4, 5, 2, 9, 7, 5]
print(df)
print (df.groupby('subject').filter(lambda x: x['rank'].mean() > 5))
输出:
   score  subject teacher  rank
0     90     math  Netwon     4
1     80  physics  Netwon     5
2     70  english  Pascal     2
3     95     math  Netwon     9
4     85  physics  Pascal     7
5     75  english  Pascal     5
   score  subject teacher  rank
0     90     math  Netwon     4
1     80  physics  Netwon     5
3     95     math  Netwon     9
4     85  physics  Pascal     7

transform()

print (df.groupby('subject').transform(lambda x: x - x. mean()))
输出:
   score  rank
0   -2.5  -2.5
1   -2.5  -1.0
2   -2.5  -1.5
3    2.5   2.5
4    2.5   1.0
5    2.5   1.5

apply()

相对于前述的分组对象的各个方法,apply()比它们更灵活。

def rank_score(x): #创建一个函数
    x['rank_score'] = x['score'] * x['rank'].std()
    return x
print (df_subject.apply(rank_score))
输出:
   score  subject teacher  rank  rank_score
0     90     math  Netwon     4  318.198052
1     80  physics  Netwon     5  113.137085
2     70  english  Pascal     2  148.492424
3     95     math  Netwon     9  335.875721
4     85  physics  Pascal     7  120.208153
5     75  english  Pascal     5  159.099026
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!