Pandas学习笔记

Pandas

  • Pandas入门篇
    • 简介
    • Pandas基本数据结构
      • Series
        • Series创建
        • Series索引
      • DataFrame
        • DataFrame创建
        • DataFrame索引
        • 修改
  • Pandas快速进阶篇
    • Series与DataFrame中的索引`Index`
      • 索引的删除`drop`
      • 索引的选取和过滤
      • 索引的切片选取数据
    • pandas中的数据运算与算术对齐
      • 在算术方法中的填充值`add`
    • DataFrame与Series之间的运算
    • 函数应用与映射
      • 函数应用和映射 `apply`
    • 排序与排名 `sort_index`
    • 带有重复值的轴索引 `is_unique`
    • 汇总计算描述统计 `sum`
    • 唯一值、值计数与成员资格 `unique`、`value_counts`、`isin`
    • 缺失值处理 `dropna`
    • 填充缺失数据 `fillna`
    • Pandas中的字符串操作
      • 字符串对象方法
    • Pandas中的日期时间处理
      • 字符串与日期时间类型的相互转化
  • Pandas 高级篇
    • 数据规整
      • 合并数据集
      • 连结数据 `concat`
      • 合并重叠数据
      • 重塑与轴向选择
        • 层次化索引与数据重塑
      • 数据转换
        • 清除重复数据`drop_duplicates`
        • 利用函数和映射进行转换`map`
        • 替换值`fillna`、`replace`
        • 数据拆分`cut`、`qcut`
        • 检查和过滤异常值
    • 数据加载、存储与解析
      • 读取/加载
      • 存储

Pandas入门篇

简介

pandas 是一个开源的,BSD许可的库,为Python编程语言提供了高性能,易于使用的数据结构和数据分析工具。
官网:http://pandas.pydata.org/

Pandas基本数据结构

主要有两个数据结构:Series 、DataFrame

Series

Series 是一种类似于一维数组的对象,它由一组数据以及一组与之相关的数据标签(即索引)组成。

Series创建

使用list创建Series

# 创建Series
obj = Series([1,2,3,4])
obj.values   # 值
obj.index   # 索引

使用字典创建Series,字典的键就是Series中的索引

data = {'a':1,'b':2}
obj = Series(data)
obj.index = ['e','f']  # 索引可以通过赋值方式修改

Series索引

#自定义索引
obj = Series([1,2,3,4],index=['a','b','c','d'])
obj['a']   # 选取单个值
obj[['a','b','c']]   # 选取一组值

DataFrame

DataFrame是一个 表格型 的数据结构 它含有一组 有序的列 每列可以是 不同的值类型 数值、字符串、布尔值等 。 Dataframe 既有行索引也有列索引 它可以被看做由 Series 组成的字典 共用同一个索引 。跟其他类似的数据结构相比 如 R 的 dataframe ), Data frame 中 面向行面向列 的操作基本上是平衡的。其实 , Dataframe 中的数据是以一个或多个二维块存放的而不是列表、字典或别的一维数据结构 。

DataFrame创建

由等长列表或Numpy数组构成的字典来创建DataFrame

data = {'state':['a','b','c'],
       'year':[2000,2001,2002],
       'pop':[1.2,1.3,1.4]}
frame = DataFrame(data)
#如果指定列序列,则DataFrame的列就会按照指定顺序进行
DataFrame(data,columns=['year','state','pop'])

使用嵌套字典创建DataFrame,外层字典的键作为列,内层键则作为行索引

pop = {'Nevada':{2001:2.4,2002:2.9},
      'Ohio':{2000:1.5,2001:1.7,2002:3.6}}
frame = DataFrame(pop)
frame.T   # 转置

# 设置index和columns的name
frame.index.name='year'
frame.columns.name='state'
frame.values   # 获取值

DataFrame索引

通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series

frame['state']
frame.state

修改

列可以通过赋值的方式进行修改

frame['in'] = 32
frame['in'] = np.arange(3.)

将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值

var = Series([-1.2,-1.5],index=[0,2])
frame['in'] = var
frame

为不同的列赋值会产生一个新的列,用del关键字删除一列

frame['good']= frame.state == 'b'
del frame['good']

Pandas快速进阶篇

Series与DataFrame中的索引Index

pandas的索引对象负责管理轴标签和其他元数据(比如轴名称)。构建Series或DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index
Index对象是不可修改的(immutable)

obj = Series(range(3),index=['a','b','c'])
index = obj.index
# out: 
Index(['a', 'b', 'c'], dtype='object')

index[1]='d' # 不可修改
# out:
TypeError: Index does not support mutable operations

索引的删除drop

删除索引,即删除该索引对应的行数据。

data = DataFrame(np.arange(16).reshape((4,4)),
				index=['Ohio','Colorado','Utah','New York'],
				columns=['one','two','three','four'])
data.drop(['Ohio'])  # 删除行,drop默认 axis=0为行
data.drop(['one'],axis=1)  # 删除列

索引的选取和过滤

obj = Series(np.arange(4.),index=['a','b','c','d'])
obj['b']
obj[1]
obj[[1,3]]
obj[obj<2]
obj<2
obj[['b','a']]

索引的切片选取数据

利用标签的切片运算与普通的Python切片操作不同,其末端是包含的

obj['b':'c']
# out:
b   1
c   2

# 设置
obj['b':'c'] = 5
#out:
a	0
b	5
c	5
d	3

pandas中的数据运算与算术对齐

pandas最重要的一个功能是,它可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集,如果某个索引只在一个对象中存在,在相加的结果为NaN

Series

s1 = Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])
s2 = Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])
s1
#out:
a    7.3
c   -2.5
d    3.4
e    1.5
dtype: float64

s2
# out:
a   -2.1
c    3.6
e   -1.5
f    4.0
g    3.1
dtype: float64

s1+s2
# out:
a    5.2
c    1.1
d    NaN
e    0.0
f    NaN
g    NaN
dtype: float64

DataFrame

df1 = DataFrame(np.arange(9.).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])
df2 = DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])

df1
# out:
b	c	d
Ohio	0.0	1.0	2.0
Texas	3.0	4.0	5.0
Colorado	6.0	7.0	8.0

df2
# out:
b	d	e
Utah	0.0	1.0	2.0
Ohio	3.0	4.0	5.0
Texas	6.0	7.0	8.0
Oregon	9.0	10.0	11.0

df1 + df2
# out:
b	c	d	e
Colorado	NaN	NaN	NaN	NaN
Ohio	3.0	NaN	6.0	NaN
Oregon	NaN	NaN	NaN	NaN
Texas	9.0	NaN	12.0	NaN
Utah	NaN	NaN	NaN	NaN

在算术方法中的填充值add

在对不同的索引对象进行算术运算时,当一个对象中的某个轴标签在另一个对象中找不到时填充一个特殊值,如果两个对象合并后某个值在两个对象中都不存在时,还是为NaN。

df1.add(df2,fill_value=0)
# out:
b	c	d	e
Colorado	6.0	7.0	8.0	NaN
Ohio	3.0	1.0	6.0	5.0
Oregon	9.0	NaN	10.0	11.0
Texas	9.0	4.0	12.0	8.0
Utah	0.0	NaN	1.0	2.0

DataFrame灵活的算术运算:

方法 说明
add 用于加法(+)的方法
sub 用于减法(-)的方法
div 用于除法(/)的方法
mul 用于乘法(*)的方法

DataFrame与Series之间的运算

函数应用与映射

默认情况下DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播。

frame = DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
series=frame.iloc[0]

frame
# out:
b	d	e
Utah	0.0	1.0	2.0
Ohio	3.0	4.0	5.0
Texas	6.0	7.0	8.0
Oregon	9.0	10.0	11.0

series
# out:
b    0.0
d    1.0
e    2.0
Name: Utah, dtype: float64

frame - series
# out:
b	d	e
Utah	0.0	0.0	0.0
Ohio	3.0	3.0	3.0
Texas	6.0	6.0	6.0
Oregon	9.0	9.0	9.0

函数应用和映射 apply

frame = DataFrame(np.random.randn(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])

frame
# out:
b	d	e
Utah	-0.431738	-0.083715	-0.557972
Ohio	1.115518	-1.580615	-0.682726
Texas	0.751603	0.123504	0.165463
Oregon	0.405330	-0.718213	-0.096647

np.abs(frame)
# out:
b	d	e
Utah	0.431738	0.083715	0.557972
Ohio	1.115518	1.580615	0.682726
Texas	0.751603	0.123504	0.165463
Oregon	0.405330	0.718213	0.096647

将函数应用到由各列或行所形成的一维数组上。


f = lambda x: x.max() - x.min()

frame.apply(f)
# out:
b    1.547256
d    1.704119
e    0.848189
dtype: float64

frame.apply(f,axis=1)
# out:
Utah      0.474256
Ohio      2.696133
Texas     0.628099
Oregon    1.123542
dtype: float64

元素级的Python函数也是可以用的,Series 也有一个用于元素级别函数的map方法

format = lambda x: '%.2f' % x
frame.applymap(format)
# out:
b	d	e
Utah	-0.43	-0.08	-0.56
Ohio	1.12	-1.58	-0.68
Texas	0.75	0.12	0.17
Oregon	0.41	-0.72	-0.10

frame['e'].map(format)
# out:
Utah      -0.56
Ohio      -0.68
Texas      0.17
Oregon    -0.10
Name: e, dtype: object

排序与排名 sort_index

obj = Series(range(4),index=['d','a','b','c'])
obj.sort_index()
#out:
a    1
b    2
c    3
d    0
dtype: int64
frame = DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c'])
frame.sort_index()
#out:
d	a	b	c
one	4	5	6	7
three	0	1	2	3

frame.sort_index(axis=1)
# out:
a	b	c	d
three	1	2	3	0
one	5	6	7	4

frame
# out:
d	a	b	c
three	0	1	2	3
one	4	5	6	7

# 数据默认是按升序排序的,但也可以降序排列
frame.sort_index(axis=1,ascending=False)
# out:
d	c	b	a
three	0	3	2	1
one	4	7	6	5

带有重复值的轴索引 is_unique

判定索引的值是否重复

obj = Series(range(5),index=['a','a','b','b','c'])
obj.index.is_unique

汇总计算描述统计 sum

pandas 对象拥有一组常用的数学和统计方法。它们大部分都属于约简和汇总统计,用于从Series中提取单个值(如summean)或从DataFrame的行或列中提取一个Series。跟对应的Numpy数组方法相比,它们都是基于没有缺失数据的假设而构建的。

df = DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],index=['a','b','c','d'],columns=['one','two'])
df
# out:
	one	two
a	1.40	NaN
b	7.10	-4.5
c	NaN		NaN
d	0.75	-1.3

df.sum()
# out:
one    9.25
two   -5.80
dtype: float64

df.sum(axis=1)
# out:
a    1.40
b    2.60
c    0.00
d   -0.55
dtype: float64

NA值会自动被排除,除非整个切片(这里指的是行或列)都是NA。通过skipna选项可以禁用该功能

df.mean(axis=1,skipna=False)
# out:
a      NaN
b    1.300
c      NaN
d   -0.275
dtype: float64

累积型的方法

df.cumsum()

既不是间接统计也不是累积型

df.describe()

唯一值、值计数与成员资格 uniquevalue_countsisin

从一组数中抽取唯一值:unique函数

u = obj.unique()

返回的值是无序的,如果需要排序,可以用u.sort()

value_counts 用于计算一个Series中各值出现的频率,默认情况下,Series统计出来的值是按降序排列的

obj.value_counts()

value_counts还有一个顶级的pandas方法,可用于任何的数组或序列

pd.value_counts(obj.values,sort=False)

isin ,用于判断矢量化成员资格,可用于选取Series或DataFrame 中的数据子集

obj.isin(['1','3'])

value_countsapply 结合起来应用, DataFrame 没有 value_counts 方法

data.apply(pd.value_counts).fillna(0)
# out:
Qu1	Qu2	Qu3
1	1.0	1.0	1.0
2	0.0	2.0	1.0
3	2.0	2.0	0.0
4	2.0	0.0	2.0
5	0.0	0.0	1.0

缺失值处理 dropna

缺失数据(missing data)在大部分数据分析应用中都很常见。pandas的设计目标之一就是让缺失数据的处理任务尽量轻松。例如,pandas对象上的所有描述统计都排除了缺失数据
pandas内置的none值也会当做缺失值处理

string_data = Series(['a','b',np.nan,'c'])
string_data

# out:
0      a
1      b
2    NaN
3      c
dtype: object

string_data.isnull()
# out:
0    False
1    False
2     True
3    False
dtype: bool
方法 说明
dropna 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈(yu)值调节对缺失值的容忍度
fillna 用指定值或插值方法(如ffillbfill)填充缺失数据
isnull 返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值/NA,该对象的类型与源类型一样
notnull isnull的否定式

利用dropna()过滤掉缺失值,dropna返回的是非空数据和索引值的Series

data = Series([1,np.nan,2])
data.dropna()
# Out:
0	1
2	2

DataFramedropna的处理复杂一点,默认丢弃包含NAN的行
传入 how='all' ,将只丢弃全为NAN的行
DataFramedropna只删除全部为NAN的某列的话,只需要传入一个:axis=1即可

填充缺失数据 fillna

df
# Out:
	one		two
a	1.40	NaN
b	7.10	-4.5
c	NaN	NaN
d	0.75	-1.3

df.fillna(0)
# Out:
	one		two
a	1.40	0.0
b	7.10	-4.5
c	0.00	0.0
d	0.75	-1.3

df.fillna({'one':1,'two':2})
# Out:
	one		two
a	1.40	2.0
b	7.10	-4.5
c	1.00	2.0
d	0.75	-1.3

fillna 默认会返回新对象,但也可以实现对原对象的修改

df.fillna(0,inplace=True)

Pandas中的字符串操作

字符串对象方法

  • split()函数 拆分字符串
  • strip()函数 去空白字符,包括回车
  • "字符"+号进行字符串的连结
  • 字符串连结更好的方法建议用 join
  • 可以用 in 检测子串 ,也可用indexfind
  • count 返回子串出现的次数
  • replace 替换,可以用空字符串来实现相当于删除的功能

Pandas中的日期时间处理

时间序列数据的意义取决于具体的应用场景,主要有以下几种:

  • 时间戳(timestamp),特定的时刻
  • 固定时期(period),如2008年10月
  • 时间间隔(interval,由起始和结束时间戳表示。时期(period)可以被看做间隔(interval)的特例
from datetime import datetime
now = datetime.now()
now
# Out:
datetime.datetime(2019, 5, 23, 13, 49, 15, 480776)

now.year,now.month,now.day,now.hour,now.minute,now.second,now.microsecond
# Out:
(2019, 5, 23, 13, 49, 15, 480776)

delta = datetime(2011,1,7)-datetime(2008,6,24,8,15)
delta
# Out:
datetime.timedelta(days=926, seconds=56700)

delta.days
# Out:
926

delta.seconds
# Out:
56700

from datetime import timedelta
start = datetime(2011,1,7)
start
# Out:
datetime.datetime(2011, 1, 7, 0, 0)

start + timedelta(12)
# Out:
datetime.datetime(2011, 1, 19, 0, 0)

start - 2 * timedelta(12)
# Out:
datetime.datetime(2010, 12, 14, 0, 0)

2 * timedelta(12)
# Out:
datetime.timedelta(days=24)

字符串与日期时间类型的相互转化

stamp = datetime(2011,1,3)
str(stamp)
# Out:
'2011-01-03 00:00:00'

stamp.strftime('%Y-%m-%d')
# Out:
'2011-01-03'
value = '2011-01-03'
datetime.strptime(value,'%Y-%m-%d')
# Out:
datetime.datetime(2011, 1, 3, 0, 0)

datestrs = ['7/6/2011','8/6/2011']
[datetime.strptime(x,'%m/%d/%Y') for x in datestrs]
# Out:
[datetime.datetime(2011, 7, 6, 0, 0), datetime.datetime(2011, 8, 6, 0, 0)]

from dateutil.parser import parse
parse('2011-01-03')
# Out:
datetime.datetime(2011, 1, 3, 0, 0)

parse('Jan 31,1997 10:45 PM')
# Out:
datetime.datetime(2019, 1, 31, 22, 45)

parse('6/12/2011',dayfirst=True)
# Out:
datetime.datetime(2011, 12, 6, 0, 0)

parse('6/12/2011',dayfirst=False)
# Out:
datetime.datetime(2011, 6, 12, 0, 0)

pandas 通常是用于处理成组日期的,不管这些日期是DataFrame的轴索引还是列索引。
to_datetime方法可以解析多种不同的日期表示形式。对标准日期格式(如ISO8601)的解析非常快。
可以处理缺失值
NaT:(not a time) 是 pandas 中时间戳数据的NA值

pd.to_datetime(datestrs)
# Out:
DatetimeIndex(['2011-07-06', '2011-08-06'], dtype='datetime64[ns]', freq=None)

datestrs + [None]
# Out:
['7/6/2011', '8/6/2011', None]

idx = pd.to_datetime(datestrs + [None])
idx
# Out:
DatetimeIndex(['2011-07-06', '2011-08-06', 'NaT'], dtype='datetime64[ns]', freq=None)

idx[2]
# Out:
NaT

pd.isnull(idx)
# Out:
array([False, False,  True])

Pandas学习笔记_第1张图片
pandas 最基本的时间序列类型就是以时间戳(通常以Python字符串或datetime对象表示)为索引的Series

dates =[datetime(2011,1,2),datetime(2012,2,3),datetime(2013,2,5),datetime(2014,4,6),datetime(2015,5,6),datetime(2016,4,6)]

ts = Series(np.random.randn(6),index=dates)
ts
# Out:
2011-01-02   -0.300655
2012-02-03    0.591874
2013-02-05   -1.414878
2014-04-06   -1.045828
2015-05-06    0.618211
2016-04-06    0.960725
dtype: float64

索引选取,子集构建

stamp = ts.index[2]
ts[stamp]
# Out:
-1.4148777980696403

ts['1/2/2011']
# Out:
-0.3006545366535157

ts['20110102']
# Out:
-0.3006545366535157

对于较长的时间序列,只需传入“年”或“年月”即可轻松选取数据的切片:

longer_ts = Series(np.random.randn(1000),index=pd.date_range('1/1/2000',periods=1000))
longer_ts['2001']
longer_ts['2001-04']

生成日期范围:date_range
默认情况下,date_range会产生按天计算的时间点,可以传入开始或结束日期来构造一段时间列表

index = pd.date_range('4/1/2012','5/1/2012')
index
# Out:
DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04',
               '2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08',
               '2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12',
               '2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16',
               '2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20',
               '2012-04-21', '2012-04-22', '2012-04-23', '2012-04-24',
               '2012-04-25', '2012-04-26', '2012-04-27', '2012-04-28',
               '2012-04-29', '2012-04-30', '2012-05-01'],
              dtype='datetime64[ns]', freq='D')
              
pd.date_range(start='4/1/2012',periods=20)
# Out:
DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04',
               '2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08',
               '2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12',
               '2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16',
               '2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20'],
              dtype='datetime64[ns]', freq='D')

pd.date_range(end='6/1/2012',periods=20)
# Out:
DatetimeIndex(['2012-05-13', '2012-05-14', '2012-05-15', '2012-05-16',
               '2012-05-17', '2012-05-18', '2012-05-19', '2012-05-20',
               '2012-05-21', '2012-05-22', '2012-05-23', '2012-05-24',
               '2012-05-25', '2012-05-26', '2012-05-27', '2012-05-28',
               '2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01'],
              dtype='datetime64[ns]', freq='D')

Pandas 高级篇

数据规整

合并数据集

pandas 对象中的数据可以通过一些内置的方式进行合并;
pandas.merge 可根据一个或多个键将不同DataFrame中的行连接起来。SQL或其他关系型数据库的用户对此应该会比较熟悉,因为它实现的就是数据库的连接操作。
pandas.concat 可以沿着一条轴将多个对象堆叠到一起。
combine_first 可以将重复数据编接在一起,用一个对象中的值填充另一个对象中的缺失值。

df1 = DataFrame({'key':['b','b','a','c','a','a','b'],'data1':range(7)})
df2 = DataFrame({'key':['a','b','d'],'data2':range(3)})
df1
# Out:
	key	data1
0	b	0
1	b	1
2	a	2
3	c	3
4	a	4
5	a	5
6	b	6

df2
# Out:
	key	data2
0	a	0
1	b	1
2	d	2

# 默认情况下,merge采用的是"inner连结",取交集部分,没有交集的会舍弃掉
pd.merge(df1,df2)
# Out:
	key	data1	data2
0	b	0	1
1	b	1	1
2	b	6	1
3	a	2	0
4	a	4	0
5	a	5	0

pd.merge(df1,df2,on='key')
# Out:
	key	data1	data2
0	b	0	1
1	b	1	1
2	b	6	1
3	a	2	0
4	a	4	0
5	a	5	0

df3 = DataFrame({'lkey':['b','b','a','c','a','a','b'],'data1':range(7)})
df4 = DataFrame({'rkey':['a','b','d'],'data2':range(3)})

# 如果两个对象的列名不同,也可以分别进行指定:
pd.merge(df3,df4,left_on='lkey',right_on='rkey')
# Out:
	lkey data1 rkey	data2
0	b		0	b	1
1	b		1	b	1
2	b		6	b	1
3	a		2	a	0
4	a		4	a	0
5	a		5	a	0
 
# 可以通过merge的how参数来指定左连接,右连接合外连接.
# how=outer,是取数据集的并集,组合了左连结与右连结的结果

pd.merge(df1,df2,how='outer') # 外连接
# Out:
	key	data1	data2
0	b	0.0		1.0
1	b	1.0		1.0
2	b	6.0		1.0
3	a	2.0		0.0
4	a	4.0		0.0
5	a	5.0		0.0
6	c	3.0		NaN
7	d	NaN		2.0

pd.merge(df1,df2,how='left') # 左连接
# Out:
	key	data1	data2
0	b	0		1.0
1	b	1		1.0
2	a	2		0.0
3	c	3		NaN
4	a	4		0.0
5	a	5		0.0
6	b	6		1.0

pd.merge(df1,df2,how='right') # 右连接
# Out:
	key	data1	data2
0	b	0.0		1
1	b	1.0		1
2	b	6.0		1
3	a	2.0		0
4	a	4.0		0
5	a	5.0		0
6	d	NaN	2

left = DataFrame({'key1':['foo','foo','bar'],
                 'key2':['one','two','one'],
                 'lval':[1,2,3]})
right = DataFrame({
    'key1':['foo','foo','bar','bar'],
    'key2':['one','one','one','two'],
    'rval':[4,5,6,7]
})

left
# Out:
key1	key2	lval
0	foo	one	1
1	foo	two	2
2	bar	one	3

right
# Out:
	key1	key2	rval
0	foo	one	4
1	foo	one	5
2	bar	one	6
3	bar	two	7

pd.merge(left,right,on=['key1','key2'],how='outer')
# Out:
	key1	key2	lval	rval
0	foo	one	1.0	4.0
1	foo	one	1.0	5.0
2	foo	two	2.0	NaN
3	bar	one	3.0	6.0
4	bar	two	NaN	7.0

连结数据 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])

# Out:
a    0
b    1
c    2
d    3
e    4
f    5
g    6
dtype: int64

默认情况下,concat 是在 axis= 0 上工作,最终产生一个Series,如果传入axis=1,则最终产生一个DataFrame(axis=1在列上工作)

pd.concat([s1,s2,s3],axis=1)

# Out:
	0	1	2
a	0.0	NaN	NaN
b	1.0	NaN	NaN
c	NaN	2.0	NaN
d	NaN	3.0	NaN
e	NaN	4.0	NaN
f	NaN	NaN	5.0
g	NaN	NaN	6.0

可以利用concat函数的join= inner 参数来取两个连接的交集

pd.concat([s1,s4],axis=1,join='inner')

# Out:
	0	1
a	0	0
b	1	5

如果想在连接轴上创建层次索引,可以给keys传入一个列表

pd.concat([s1,s2,s3],keys=['one','two','three'])

# Out:
one    a    0
       b    1
two    c    2
       d    3
       e    4
three  f    5
       g    6
dtype: int64

合并重叠数据

有一种数据组合问题不能用简单的合并(merge)或连接(concat)运算来处理,比如:索引全部或部分重叠的两个数据集
Series中有一个方法可以实现重叠数据的对齐

a = Series([np.nan,2.5,np.nan,3.5,4.5,np.nan],index=['f','e','d','c','b','a'])
b = Series(np.arange(len(a),dtype=np.float64),index=['f','e','d','c','b','a'])
b[:-2].combine_first(a[2:])
# Out:
a    NaN
b    4.5
c    3.0
d    2.0
e    1.0
f    0.0
dtype: float64

DataFrame,combine_first 也会在列上做同样的事情,因此可以看做参数对象中的数据为调用者对象的确实数据“打补丁”

df1 = DataFrame({'a':[1.,np.nan,5.,np.nan],
                'b':[np.nan,2.,np.nan,6.],
                'c':range(2,18,4)})
df2 = DataFrame({'a':[5.,4.,np.nan,3.,7.],
                'b':[np.nan,3.,4.,6.,8.]})
df1.combine_first(df2)
# Out:
a	b	c
0	1.0	NaN	2.0
1	4.0	2.0	6.0
2	5.0	4.0	10.0
3	3.0	6.0	14.0
4	7.0	8.0	NaN

重塑与轴向选择

层次化索引与数据重塑

data = Series(np.random.rand(10),index=[['a','a','a','b','b','b','c','c','d','d'],
                                       [1,2,3,1,2,3,1,2,2,3]])
data
Out:
a  1    0.621196
   2    0.545708
   3    0.553969
b  1    0.923237
   2    0.471105
   3    0.680784
c  1    0.903870
   2    0.576824
d  2    0.600520
   3    0.143685
dtype: float64

stack: 将数据的列“旋转”为行
unstack:将数据的行“旋转”为列

data = DataFrame(np.arange(6).reshape((2,3)),index=pd.Index(['Ohio','Colorado'],name='state'),
                columns=pd.Index(['one','two','three'],name='number'))
data
# Out:
number	one	two	three
state			
Ohio	0	1	2
Colorado	3	4	5

data.stack()
# Out:
state     number
Ohio      one       0
          two       1
          three     2
Colorado  one       3
          two       4
          three     5
dtype: int64

data.unstack()
# Out:
number  state   
one     Ohio        0
        Colorado    3
two     Ohio        1
        Colorado    4
three   Ohio        2
        Colorado    5
dtype: int64

默认情况下,unstack操作的是最内层(stack也是如此)。传入分层级别的编号或名称即可对其他级别进行unstack操作

result = data.stack()
result
# Out
state     number
Ohio      one       0
          two       1
          three     2
Colorado  one       3
          two       4
          three     5
dtype: int64

result.unstack()
# Out:
number		one	two	three
state			
Ohio		0	1	2
Colorado	3	4	5

result.unstack(0)  # 0代表最外层
# Out:
state	Ohio	Colorado
number		
one		0	3
two		1	4
three	2	5

result.unstack('state')
# Out:
state	Ohio	Colorado
number		
one		0	3
two		1	4
three	2	5

stackunstack 是可逆的

数据转换

清除重复数据drop_duplicates

DataFrame的duplicated 方法返回一个布尔型Series,表示各行是否是重复行;
drop_duplicates方法,它用于返回一个移除了重复行的DataFrame;
这两个方法默认会判断全部列,也可以指定部分列进行重复项判断。

data = DataFrame({'k1':['one']*3 + ['two']*4,'k2':[1,1,2,3,3,4,4]})
data
# Out:
	k1	k2
0	one	1
1	one	1
2	one	2
3	two	3
4	two	3
5	two	4
6	two	4

data.duplicated()
# Out:
0    False
1     True
2    False
3    False
4     True
5    False
6     True
dtype: bool

data.drop_duplicates()
# Out:
	k1	k2
0	one	1
2	one	2
3	two	3
5	two	4

data['v1'] = range(7)
data
# Out:
	k1	k2	v1
0	one	1	0
1	one	1	1
2	one	2	2
3	two	3	3
4	two	3	4
5	two	4	5
6	two	4	6

data.drop_duplicates(['k1'])
# Out:
	k1	k2	v1
0	one	1	0
3	two	3	3

# 默认保留的是第一个出现的值组合,如果要改变,传入 `keep`参数
data.drop_duplicates(['k1'],keep='first')
# Out:
	k1	k2	v1
2	one	2	2
6	two	4	6

利用函数和映射进行转换map

替换值fillnareplace

数据拆分cutqcut

为了便于分析,连续数据常常被离散化或拆分为“面元”(bin)
qcut : 可以根据样本分位数对数据进行面元拆分,可以得到大小基本相等的面元。
参考网址: https://blog.csdn.net/tcy23456/article/details/84797418

ages = [20,22,25,27,21,23,37,31,61,45,41,32]
bins = [18,25,35,60,100]
cats = pd.cut(ages,bins)
pd.cut(data,4,precision=2) # 等长、均匀分布面元拆分

检查和过滤异常值

数据加载、存储与解析

读取/加载

read_csv

read_csv:默认逗号分隔,默认首行作为列名称

df = pd.read_csv('test.csv')

pd.read_csv( ) 读取没有明显 列名称的文件,就不让首行 为 列名称。参数 header = None

df = pd.read_csv('test.csv' ,header=None)

自定义 列名称 ,参数 names = [ ]

df = pd.read_csv('test.csv' ,names = ['a','b','c','d','message']) 

names=[] 的长度不匹配 列数量,会自动把 names 匹配到最后,数量不足的都是 行索引index

df = pd.read_csv('test.csv' ,names = ['aa','bb','cc']) 
# Out:
		aa	bb	cc
1	2	3	4	hello
5	6	7	8	world
9	10	11	12	foo

names=[] 的长度超出列数量,会匹配列,超出部分都是 Nan

df = pd.read_csv('test.csv' ,names = ['aa','bb','cc','dd','ee','ff','gg']) 

自己 设置 某列的值为 行索引 ,参数: index_col = ''

df = pd.read_csv('test.csv' ,names = ['aa','bb','cc','dd','message'] ,index_col ='message')

设置多列作为 行索引

df = pd.read_csv('test.csv' ,index_col = ['key1','key2'])

使用参数 skiprows = [] , 实现 跳过某些无效行或者 注释 行

df = pd.read_csv('test.csv',skiprows=[0,2,3])

读取的时候让 xxx 为 nan , na_values = [ xxx,yyy,...]

df = pd.read_csv('test.csv',na_values=[2,12])

指定不同的 列 的 不同的 值 为 nan ,参数 na_values = { '列名称':'具体值' ,... }

nans = {'something':['two'] ,'message':['foo','world'] }
df = pd.read_csv('test.csv',na_values=nans)

读取的数据是纯字符串的,可以用 dtype = 指明 类型

df = pd.read_csv('test.csv',dtype=int)

选取几列 读出来 , usecols = []

df = pd.read_csv('data/ex7.csv',dtype=int ,usecols=['a','c'])

也可以是 先 读取整体 ,再 提取几列,更为灵活

df[['a','c']]

read_table

read_table :需要指定分隔符sep=',',默认首行作为列名称,读取 不规则 的 分隔符数据。用 正则 表达式 作为 分隔符。不需要导入 re,不需要创建 对象

df = pd.read_table('test.csv',sep=',')
df = pd.read_table('test.csv',sep='\s+')

read_clipboard
读取剪贴板的内容

pd.read_clipboard()

存储

.to_csv()

df = DataFrame(
    np.random.randint(40,100,(25,4)),
    index = range(1,26),
    columns = '语文,数学,英语,体育'.split(',')
)
# 默认存储 .行列索引都存储 
df.to_csv( 'out1.csv')
DataFrame([[10,20,30],[20,40,60,70]]).to_csv('out2.csv')

# 参数 header = False 。不存  column
df.to_csv('out4.csv',index=False ,header=False)

# 如果数据中 有 nan
# 参数 na_rep = ' '   nan换成 xxx 显示
df.to_csv('out5.csv',na_rep='Null')

.to_excel()

xxx.to_excel(excel_writer, sheet_name='Sheet1', na_rep='',。。。。)
   excel_writer:文件名
   sheet_name: 存的时候表的名称
   其他参数同 csv

预览 sys.stdout .然后再写存储

df.to_csv(sys.stdout  ,index=False)

你可能感兴趣的:(人工智能)