pandas有两个基本的数据结构:Series和DataFrame。
- Series数据结构类似于一维数组,但它是一组数据和一组对应的索引组成,通过一个列表数据即可产生最简单的Series数据。
- DataFrame为表格型数据。 (类似Excel结构)
1.pandas数据结构
- 1.创建Series (索引+值)
from pandas import Series
import pandas as pd
obj = Series([1, -2, 3, -4])
obj
0 1
1 -2
2 3
3 -4
dtype: int64
obj2 = Series([1, -2, 3, -4], index=['a', 'b', 'c', 'd'])
obj2
a 1
b -2
c 3
d -4
dtype: int64
obj2.values
array([ 1, -2, 3, -4], dtype=int64)
obj2.index
Index(['a', 'b', 'c', 'd'], dtype='object')
obj2['b'] # 取值
-2
obj2['c'] = 23 # 赋值
obj2[['c', 'd']]
c 23
d -4
dtype: int64
obj2
a 1
b -2
c 23
d -4
dtype: int64
obj2[obj2 < 0 ]
b -2
d -4
dtype: int64
obj2 * 2
a 2
b -4
c 46
d -8
dtype: int64
import numpy as np
np.abs(obj2)
a 1
b 2
c 23
d 4
dtype: int64
data = {
'张三':92,
'李四':78,
'王五':68,
'小明':82
}
obj3 = Series(data) # 通过字典数据来创建Series,索引和值一一对应
obj3
张三 92
李四 78
王五 68
小明 82
dtype: int64
names = ['张三', '李四', '王五', '小明']
obj4 = Series(data, index=names)
obj4
张三 92
李四 78
王五 68
小明 82
dtype: int64
#Series对象和索引都有name属性,我们可以给Series定义名称
obj4.name = 'math' # 对象
obj4.index.name = 'students' # 索引
obj4
students
张三 92
李四 78
王五 68
小明 82
Name: math, dtype: int64
- 2.创建DataFrame (二维表)
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
data = {
'name':['张三', '李四', '王五', '小明'],
'sex':['female', 'female', 'male', 'male'],
'year':[2001, 2001, 2003, 2002],
'city':['北京', '上海', '广州', '北京']
}
df = DataFrame(data)
df # 输出二维表
#通过columns指定列索引的排列顺序
df = DataFrame(data, columns=['name', 'sex', 'year', 'city'])
df
# index指定行索引
df = DataFrame(data, columns=['name', 'sex', 'year', 'city'],index=['a', 'b', 'c', 'd'])
df
=====================================
data2 = {
'sex':{'张三':'female','李四':'female','王五':'male'},
'city':{'张三':'北京','李四':'上海','王五':'广州'}
}
df2 = DataFrame(data2)
df2
#给行列索引添加名字
df.index.name = 'id'
df.columns.name = 'std_info'
-
df.index(行索引)
df.index Index(['a', 'b', 'c', 'd'], dtype='object')
-
df.columns(列索引)
df.columns Index(['name', 'sex', 'year', 'city'], dtype='object')
- 3.索引对象
Series的索引和DataFrame的行和列索引都是索引对象,索引对象时不可以进行修改的,否则会报错
'sex' in df.columns
True
'f' in df.index
False
- 1.重新索引
索引对象是无法进行修改的,重新索引并不是给索引重新命名,而是对索引重新排序。如果某个索引值不存在的话,就会引入缺失值。
(1)np.reindex()函数的各参数使用说明
- 1.index
- 行索引
- 2.columns
- 列索引
- 3.method
- 填充缺失值的方法,参数值为ffill或pad时为向前填充,参数值为bfill或者backfill时为向后填充
- 4.fill_value
- 填充指定缺失值
- 5.limit
- 最大填充量
(2)一维(Series)
# Series数据
obj = Series([1, -2, 3, -4], index=['b', 'a', 'c', 'd'])
obj
b 1
a -2
c 3
d -4
dtype: int64
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2
a -2.0
b 1.0
c 3.0
d -4.0
e NaN
dtype: float64
obj = Series([1, -2, 3, -4], index=[0,2,3,5])
obj
0 1
2 -2
3 3
5 -4
dtype: int64
# 如果需要对插入的缺失值进行填充的话,可以通过method参数实现,参数值为ffill或pad时为向前填充,参数值为bfill或者backfill时为向后填充。
obj2 = obj.reindex(range(6),method='ffill') # 向前填充
obj2
0 1
1 1
2 -2
3 3
4 3
5 -4
dtype: int64
(3)二维(DataFrame)
# 对于DataFrame数据来说,行和列索引都可以重新索引
df = DataFrame(np.arange(9).reshape(3,3),index=['a','c','d'],columns=['name','id','sex']) # 创建DataFrame数据
df
# 行重新索引,空索引填充为NaN
df2 = df.reindex(['a', 'b', 'c', 'd'])
df2
# 列重新索引,需要使用columns关键字,k空列使用fill_value指定填充
df3 = df.reindex(columns=['name', 'year', 'id'], fill_value=0)
df3
- 2.更换索引(DataFrame)
- set_index()
- df2 = df.sort_values(by='grade')
- reset_index()
- df2.reset_index(drop=True)
在DataFrame数据中,如果不希望使用默认的行索引,可在创建的时候通过index参数设置行索引。
有时我们系统列数据作为行索引,这是可以通过set_index()方法来实现。
# 创建DataFrame数据
data = {
'name':['张三', '李四', '王五', '小明'],
'grade':[68, 78, 63, 92]
}
df = DataFrame(data)
df
# 排序后行索引号会改变
df2 = df.sort_values(by='grade')
df2
# 还原默认索引
df3 = df2.reset_index()
df3
# 原索引可通过drop参数进行删除
df4 = df2.reset_index(drop=True)
df4
# 创建DataFrame数据
data = {
'name':['张三', '李四', '王五', '小明'],
'sex':['female', 'female', 'male', 'male'],
'year':[2001, 2001, 2003, 2002],
'city':['北京', '上海', '广州', '北京']
}
df = DataFrame(data)
df
# 列数据为行索引
df2 = df.set_index('name')
df2
# 还原
df3 = df2.reset_index()
df3
- 3.索引和选取
- 一维Series
Series数据的选取较为简单,使用方法类似于Python的列表。
但是切片运算与Python列表略有不同,如果是**利用索引标签切片,其尾端是被包含的。**
import numpy as np
from pandas import Series,DataFrame
import pandas as pd
obj = Series([1, -2, 3, -4], index=['a', 'b', 'c', 'd'])
obj
a 1
b -2
c 3
d -4
dtype: int64
obj[1]
-2
obj['b']
-2
obj[['a','c']]
a 1
c 3
dtype: int64
obj[0:2]
a 1
b -2
dtype: int64
# 利用索引标签切片,其尾端是被包含的。
obj['a':'c']
a 1
b -2
c 3
dtype: int64
- 二维DataFrame
- 1.选取 列
通过列索引标签或者以属性的方式可以单独获取DataFrame的列数据,返回的数据为Series结构,通过两个中括号,可以获取多个列的数据。
data = {
'name':['张三', '李四', '王五', '小明'],
'sex':['female', 'female', 'male', 'male'],
'year':[2001, 2001, 2003, 2002],
'city':['北京', '上海', '广州', '北京']
}
df = DataFrame(data)
df
# 列索引标签
df['city']
0 北京
1 上海
2 广州
3 北京
Name: city, dtype: object
# 属性的方式
df.name
0 张三
1 李四
2 王五
3 小明
Name: name, dtype: object
# 通过两个中括号,可以获取多个列的数据
df[['city','sex']]
- 2.选取 行
通过行索引标签或行索引位置(0到N-1)的切片形式可选取DataFrame的行数据。
data = {
'name':['张三', '李四', '王五', '小明'],
'sex':['female', 'female', 'male', 'male'],
'year':[2001, 2001, 2003, 2002],
'city':['北京', '上海', '广州', '北京']
}
df = DataFrame(data)
df
# 列数据设置为行索引
df2 = df.set_index('name')
df2
# 行索引位置的切片形式
df2[0:2]
# 行索引标签的切片形式
df2['李四':'王五']
- loc(),按行索引标签选取数据
df2.loc['张三']
sex female
year 2001
city 北京
Name: 张三, dtype: object
df2.loc[['张三','王五']]
- iloc(),按行索引位置索引数据
df2.iloc[1]
sex female
year 2001
city 上海
Name: 李四, dtype: object
df2.iloc[[1,3]]
- 3.布尔选择
df2['sex'] == 'female'
name
张三 True
李四 True
王五 False
小明 False
Name: sex, dtype: bool
df2[df2['sex'] == 'female']
- 4.操作行和列
- 1.增加
new_data = {
'city':'武汉',
'name':'小李',
'sex':'male',
'year':2002
}
# 添加新行
df = df.append(new_data,ignore_index=True) #忽略索引值
df
df['class'] = 2018 # 增加新列
df
df['math'] = [92,78,58,69,82] # 增加新列,并指定数值
df
- 2.删除
new_df = df.drop(2) #删除行
new_df
new_df = new_df.drop('class',axis=1) #删除列
new_df
- 3.修改
# 行号3变为2, 4变为3,列“math”变为“Math”
new_df.rename(index={3:2,4:3},columns={'math':'Math'},inplace=True) # inplace可在原数据上修改
new_df
3.pandas数据运算
- 1.算术运算
pandas的数据对象在进行算术运算时,如果 有相同的索引对 则进行算术运算,如果没有则会引入缺失值,这就是数据对齐。
# Series
# a+c,Series上对齐操作
obj1 = Series([3.2,5.3,-4.4,-3.7],index=['a','c','g','f'])
obj1
a 3.2
c 5.3
g -4.4
f -3.7
dtype: float64
obj2 = Series([5.0,-2,4.4,3.4],index=['a','b','c','d'])
obj2
a 5.0
b -2.0
c 4.4
d 3.4
dtype: float64
obj1 + obj2
a 8.2
b NaN
c 9.7
d NaN
f NaN
g NaN
dtype: float64
# DataFrame数据而言,对齐操作会同时发生在行和列上
# 列:a和b,行:apple和tea
df1 = DataFrame(np.arange(9).reshape(3,3),columns=['a','b','c'], index=['apple','tea','banana'])
df1
df2 = DataFrame(np.arange(9).reshape(3,3),columns=['a','b','d'], index=['apple','tea','coco'])
df2
df1 + df2
- 2.函数应用和映射
- map函数
- 将函数套用在Series的每一个元素中
# 创建DataFrame数据
data = {
'fruit':['apple', 'orange', 'grape', 'banana'],
'price':['25元', '42元', '35元', '14元']
}
df1 = DataFrame(data)
df1
# 创建函数
def f(x):
‘’‘price以“元”进行分离,接着取第一个元素[0]’‘‘
return x.split('元')[0]
# map函数调用
df1['price'] = df1['price'].map(f)
df1
- apply函数
- 将函数套用到DataFrame的行与列中
# 创建DataFrame数据
df2 = DataFrame(np.random.randn(3,3),columns=['a','b','c'],
index=['app','win','mac'])
df2
# 创建函数
f = lambda x:x.max()-x.min()
# apply函数调用
df2.apply(f)
- applymap函数
- 将函数套用DataFrame的每个元素上
# 创建DataFrame数据
df2 = DataFrame(np.random.randn(3,3),columns=['a','b','c'],
index=['app','win','mac'])
df2
# applymap函数调用,每一个元素保留两位小数
df2.applymap(lambda x:'%.2f'%x)
- 3.排序
- 一维(Series)
- sort_index()
- 可以对索引进行排序,默认情况为升序
- sort_values()
- 对值进行排序
obj1 = Series([-2,3,2,1],index=['b','a','d','c'])
obj1
b -2
a 3
d 2
c 1
dtype: int64
obj1.sort_index() #升序
a 3
b -2
c 1
d 2
dtype: int64
obj1.sort_index(ascending=False) #降序
d 2
c 1
b -2
a 3
dtype: int64
obj1.sort_values()
b -2
c 1
d 2
a 3
dtype: int64
- 二维(DataFrame)
- sort_index()
- 通过指定轴方向,使用sort_index()函数可对行或者列索引进行排序
- sort_values()
- 根据列进行排序,可以通过sort_values()函数,把列名传给by参数即可
df2 = DataFrame(np.random.randn(3,3),columns=['a','b','c'],index=['app','win','mac'])
df2
df2.sort_values(by='b')
- 4.汇总与统计
- sum()
df = DataFrame(np.random.randn(9).reshape(3,3),columns=['a','b','c'])
df
# sum函数可以对每列进行求和汇总
df.sum()
a 0.412539
b -0.322247
c 1.266969
dtype: float64
# sum函数按行汇总,下面所有列元素相加
df.sum(axis=1)
0 2.936019
1 -1.728795
2 0.150036
dtype: float64
- describe()
data = {
'name':['张三', '李四', '王五', '小明'],
'sex':['female', 'female', 'male', 'male'],
'math':[78, 79, 83, 92],
'city':['北京', '上海', '广州', '北京']
}
df = DataFrame(data)
df
# describe方法可对每个数值型列进行统计
df.describe()
4.层次索引,具体见P60页
- 轴上有多个级别索引