本文将提到:Pandas的初识、基本操作、Series和DataFrame简介、简单操作、pandas对日期的简单处理等内容
对于数据科学家,无论是数据分析还是数据挖掘来说,Pandas是一个非常重要的Python包。它不仅提供了很多方法,使得数据处理非常简单,同时在数据处理速度上也做了很多优化,使得和Python内置方法相比时有了很大的优势。
如果你想学习Pandas,建议先看两个网站。
官网:Python Data Analysis Library
十分钟入门Pandas:10 Minutes to pandas
在第一次学习Pandas的过程中,你会发现你需要记忆很多的函数和方法。所以在这里汇总一下Pandas官方文档 中比较常用的函数和方法,以方便大家记忆。
在这个速查手册中,我们使用如下缩写:
df:任意的Pandas DataFrame对象
同时我们需要做如下的引入:
import pandas as pd
pd.read_csv(filename):从CSV文件导入数据
pd.read_table(filename):从限定分隔符的文本文件导入数据
pd.read_excel(filename):从Excel文件导入数据
pd.read_sql(query, connection_object):从SQL表/库导入数据
pd.read_json(json_string):从JSON格式的字符串导入数据
pd.read_html(url):解析URL、字符串或者HTML文件,抽取其中的tables表格
pd.read_clipboard():从你的粘贴板获取内容,并传给read_table()
pd.DataFrame(dict):从字典对象导入数据,Key是列名,Value是数据
df.to_csv(filename):导出数据到CSV文件
df.to_excel(filename):导出数据到Excel文件
df.to_sql(table_name, connection_object):导出数据到SQL表
df.to_json(filename):以Json格式导出数据到文本文件
pd.DataFrame(np.random.rand(20,5)):创建20行5列的随机数组成的DataFrame对象
pd.Series(my_list):从可迭代对象my_list创建一个Series对象
df.index = pd.date_range('1900/1/30', periods=df.shape[0]):增加一个日期索引
df.head(n):查看DataFrame对象的前n行
df.tail(n):查看DataFrame对象的最后n行
df.shape():查看行数和列数
df.info():查看索引、数据类型和内存信息
df.describe():查看数值型列的汇总统计
s.value_counts(dropna=False):查看Series对象的唯一值和计数
df.apply(pd.Series.value_counts):查看DataFrame对象中每一列的唯一值和计数
df[col]:根据列名,并以Series的形式返回列
df[[col1, col2]]:以DataFrame形式返回多列
s.iloc[0]:按位置选取数据
s.loc['index_one']:按索引选取数据
df.iloc[0,:]:返回第一行
df.iloc[0,0]:返回第一列的第一个元素
df.columns = ['a','b','c']:重命名列名
pd.isnull():检查DataFrame对象中的空值,并返回一个Boolean数组
pd.notnull():检查DataFrame对象中的非空值,并返回一个Boolean数组
df.dropna():删除所有包含空值的行
df.dropna(axis=1):删除所有包含空值的列
df.dropna(axis=1,thresh=n):删除所有小于n个非空值的行
df.fillna(x):用x替换DataFrame对象中所有的空值
s.astype(float):将Series中的数据类型更改为float类型
s.replace(1,'one'):用‘one’代替所有等于1的值
s.replace([1,3],['one','three']):用'one'代替1,用'three'代替3
df.rename(columns=lambda x: x + 1):批量更改列名
df.rename(columns={'old_name': 'new_ name'}):选择性更改列名
df.set_index('column_one'):更改索引列
df.rename(index=lambda x: x + 1):批量重命名索引
df[df[col] > 0.5]:选择col列的值大于0.5的行
df.sort_values(col1):按照列col1排序数据,默认升序排列
df.sort_values(col2, ascending=False):按照列col1降序排列数据
df.sort_values([col1,col2], ascending=[True,False]):先按列col1升序排列,后按col2降序排列数据
df.groupby(col):返回一个按列col进行分组的Groupby对象
df.groupby([col1,col2]):返回一个按多列进行分组的Groupby对象
df.groupby(col1)[col2]:返回按列col1进行分组后,列col2的均值
df.pivot_table(index=col1, values=[col2,col3], aggfunc=max):创建一个按列col1进行分组,并计算col2和col3的最大值的数据透视表
df.groupby(col1).agg(np.mean):返回按列col1分组的所有列的均值
data.apply(np.mean):对DataFrame中的每一列应用函数np.mean
data.apply(np.max,axis=1):对DataFrame中的每一行应用函数np.max
df1.append(df2):将df2中的行添加到df1的尾部
df.concat([df1, df2],axis=1):将df2中的列添加到df1的尾部
df1.join(df2,on=col1,how='inner'):对df1的列和df2的列执行SQL形式的join
df.describe():查看数据值列的汇总统计
df.mean():返回所有列的均值
df.corr():返回列与列之间的相关系数
df.count():返回每一列中的非空值的个数
df.max():返回每一列的最大值
df.min():返回每一列的最小值
df.median():返回每一列的中位数
df.std():返回每一列的标准差
pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析。它提供了大量高级的数据结构和对数据处理的方法。
pandas 有两个主要的数据结构:Series 和 DataFrame。
Series 是一个一维数组对象 ,类似于 NumPy 的一维 array。它除了包含一组数据还包含一组索引,所以可以把它理解为一组带索引的数组。
eg_创建Series对象
#1.将数组转化为Series对象
#当没有指定索引时,Series自动从0开始,步长为1创建索引。可以加index参数为其添加索引
Series1 = Series([1,2,3,4,5])
Series1 = Series([1,2,3,4,5], index = ['a','b','c','d','e'])
'''
结果:
0 1
1 2
2 3
3 4
4 5
dtype: int64
'''
#2.将字典转化为Series对象
dic = {'yang':1}
Series2 = Series(dic)
'''
结果:
yang 1
dtype: int64
'''
DataFrame是一个表格型的数据结构,它提供有序列和不同类型的列值
eg_创建DataFrame对象
#1、dataframe对象
data = {'name':['jack','tom','marry'],'age':[20,19,30],'gender':['m','m','w']}
frame = DataFrame(data)
'''
frame:
name age gender
0 jack 20 m
1 tom 19 m
2 marry 30 w
'''
#2、DataFrame 默认根据列名首字母顺序进行排序,想要指定列的顺序?传入一个列名的字典即可:
frame = DataFrame(data, columns = ['name','gender','age'])
'''
frame:
name gender age
0 jack m 20
1 tom m 19
2 marry w 30
'''
#3、如果传入的列名不存在,不会报错,但会产生一个NaN值(not a number)
frame = DataFrame(data, columns = ['name','gender','age','weight'])
'''
frame
name gender age weight
0 jack m 20 NaN
1 tom m 19 NaN
2 marry w 30 NaN
'''
'''
4、DataFrame不光可以通过字典索引的方式获取数据,还可以使用属性的方法:
frame['name'] <==> frame.name
结果:
0 jack
1 tom
2 marry
Name: name, dtype: object
'''
由numpy创建的
#由 numpy创建的 带有索引的
s1 = Series(data = np.random.randint(0,150,size = 5),index = ['python','h5','java','go','r'],name = "name")
#结果:
python 40
h5 46
java 52
go 20
r 78
Name: name, dtype: int32
#如果不指定索引,自动生成默认索引
s2 = Series(data = np.random.randint(0,150,size = 5))
#结果
0 60
1 42
2 135
3 127
4 51
dtype: int32
由列表创建的
l1 = [10,20,19,32,56]
s3 = Series(l1,index = list('abcde'))
#结果
a 10
b 20
c 19
d 32
e 35
dtype: int64
由字典创建的
s4 = Series({"Nobel" : 200, "GaoYang" : 900}, name = 'sorce')
#结果
Nobel 200
GaoYang 900
Name: score, dtype: object
'''
重建索引指的是根据index参数重新进行排序。
如果传入的索引值在数据里不存在,则不会报错,而是添加缺失值的新行。
不想用缺失值,可以用 fill_value 参数指定填充值。
'''
c1 = Series([1,2,3],index = ['a','c','b'])
'''
c1
a 1
c 2
b 3
dtype: int64
'''
c2 = c1.reindex(['b','a','c'])
'''
c2
b 3
a 1
c 2
dtype: int64
'''
c3 = c2.reindex(['c','b','a','d'])
'''
c3
c 2.0
b 3.0
a 1.0
d NaN
dtype: float64
'''
c4 = c2.reindex(['c','b','a','d'],fill_value = 0)
'''
c4
c 2
b 3
a 1
d 0
dtype: int64
'''
#fill_value 会让所有的缺失值都填充为同一个值,如果不想这样而是用相邻的元素(左或者右)的值填充,则可以用参数 ffill 和 bfill,分别为用前值填充和用后值填充
c5 = c2.reindex(['c','b','a','d']).ffill()
c6 = c2.reindex(['c','b','a','d']).bfill()
#重建索引
frame = DataFrame(np.arange(9).reshape((3,3)),index = ['a','b','c'],columns = ['aa','bb','cc'])
'''
frame
aa bb cc
a 0 1 2
b 3 4 5
c 6 7 8
'''
frame2 = frame.reindex(['a','b','c','d'])
'''
frame2 变为浮点数的原因是 NaN是float类型
aa bb cc
a 0.0 1.0 2.0
b 3.0 4.0 5.0
c 6.0 7.0 8.0
d NaN NaN NaN
'''
frame3 = frame.reindex(columns = ['aa','bb','cc','dd'])
'''
frame3
aa bb cc dd
a 0 1 2 NaN
b 3 4 5 NaN
c 6 7 8 NaN
'''
frame4 =frame.reindex(index = ['a','b','c','d'],columns=['aa','bb','cc']).ffill()
'''
frame4
aa bb cc
a 0.0 1.0 2.0
b 3.0 4.0 5.0
c 6.0 7.0 8.0
d 6.0 7.0 8.0
'''
#只能对行进行删除
data = DataFrame(np.arange(16).reshape((4,4)),index = list([1,2,3,4]),columns = ['jack','tony','lucy','herry'])
'''
data
jack tony lucy herry
1 0 1 2 3
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
data.drop([1])
'''
结果
jack tony lucy herry
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
#不光可以删除行,还可以删除列
data = DataFrame(np.arange(16).reshape((4,4)),index = list([1,2,3,4]),columns = ['jack','tony','lucy','herry'])
'''
data
jack tony lucy herry
1 0 1 2 3
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
data.drop['1']
'''
结果
jack tony lucy herry
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
data.drop('jack',axis = 1) #axis=1 时候删除列元素
'''
结果
tony lucy herry
1 1 2 3
2 5 6 7
3 9 10 11
4 13 14 15
'''
.loc[]
(全闭区间 --> 左右都包含).loc[]
(左闭右开)1、显式索引
s3 = Series(l,index = list('abcde'))
'''s3:
a 10
b 20
c 19
d 32
e 35
dtype: int64
s3['b'] <==> s3.loc['b'] --> 20
s3['a':'d'] <==> s3.loc['a':'d']
'''
2、隐式索引
'''
s3[2] = s3.iloc[2] --> 19
s3.iloc[0:2] --> a 10
b 20
dtype: int64
'''
① 索引、切片
object = Series(np.arange(4.),index = ['a','b','c','d'])
'''
object
a 0.0
b 1.0
c 2.0
d 3.0
dtype: float64
object['b'] <==> object[1] = 1.0
object[['a','b']] <==> a 0.0
b 1.0
dtype: float64
object[2:4] <==> c 2.0
d 3.0
dtype: float64
object['a':'c'] <==> a 0.0
b 1.0
c 2.0
dtype: float64
'''
注:
利用索引的切片运算与普通的 Python 切片运算不同,其末端是包含的,既包含最后一个的项。
② 赋值
object['a','b'] = 100
'''
obj
a 100.0
b 100.0
c 2.0
d 3.0
dtype: float64
'''
① 索引和切片
'''
data
jack tony lucy herry
1 0 1 2 3
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15
'''
data['jack']
data[['jack','tony']]
data[:2] # 注 这里是左闭右开的
#将两个对象相加的时候,具有相同索引的值会相加,不重叠的则会区并集,值为NaN
s1 = Series([1,2,3,4],index = ['a','b','c','d'])
'''
s1
a 1
b 2
c 3
d 4
dtype: int64
'''
s2 = Series([10,20,30,40],index = ['x','b','c','y'])
'''
s2
x 10
b 20
c 30
y 40
dtype: int64
'''
s1 + s2
'''
结果:
a NaN
b 22.0
c 33.0
d NaN
x NaN
y NaN
dtype: float64
'''
#对齐操作会同时发生在行和列上,把2个对象相加会得到一个新的对象,其索引为原来2个对象的索引的并集
df1 = DataFrame(np.arange(9.).reshape((3,3)), columns = list('abc'),index = ['beijing','shanghai','guangzhou'])
'''
df1
a b c
beijing 0.0 1.0 2.0
shanghai 3.0 4.0 5.0
guangzhou 6.0 7.0 8.0
'''
df2 = DataFrame(np.arange(12.).reshape((4,3)),columns = list('cde'),index = ['beijing','guangzhou','Tees','newyork'])
'''
df2
c d e
beijing 0.0 1.0 2.0
guangzhou 3.0 4.0 5.0
Tees 6.0 7.0 8.0
newyork 9.0 10.011.0
'''
df1 + df2
'''
结果
a b c d e
Tees NaN NaN NaN NaN NaN
beijing NaN NaN 2.0 NaN NaN
guangzhou NaN NaN 11.0NaN NaN
newyork NaN NaN NaN NaN NaN
shanghai NaN NaN NaN NaN NaN
'''
注:与Series对象一样,不重叠的索引会取并集,值为NaN,如果不想这样,可以通过add()方法进行数据填充
df1 = DataFrame(np.arange(9.).reshape((3,3)),columns = list('abc'), index = ['a1','b1','c1'])
'''
df1
a b c
a1 0.0 1.0 2.0
b1 3.0 4.0 5.0
c1 6.0 7.0 8.0
'''
df2 = DataFrame(np.arange(16.).reshape((4,4)),columns = list('abcd'),index = ['a1','b1','c1','d1'])
'''
df2
a b c d
a1 0.0 1.0 2.0 3.0
b1 4.0 5.0 6.0 7.0
c1 8.0 9.0 10.0 11.0
d1 12.0 13.0 14.0 15.0
'''
df1 + df2
'''
结果
a b c d
a1 0.0 2.0 4.0 NaN
b1 7.0 9.0 11.0 NaN
c1 14.0 16.0 18.0 NaN
d1 NaN NaN NaN NaN
'''
#通过add()来避免产生NaN值
df1.add(df2,fill_value = 0) #将空的地方先用0代替 然后再进行相加减
'''
结果
a b c d
a1 0.0 2.0 4.0 3.0
b1 7.0 9.0 11.0 7.0
c1 14.0 16.0 18.0 11.0
d1 12.0 13.0 14.0 15.0
'''
将一个lambda表达式应用到每列数据里
df2 = df1.astype(np.int32) #as type 修改类型
'''
df2
a b c
a1 0 1 2
b1 3 4 5
c1 6 7 8
'''
f = lambda x: x + 1
df2.apply(f) #每列数据都+1
'''结果
a b c
a1 1 2 3
b1 4 5 6
c1 7 8 9
'''
f2 = lambda x: x.max() - x.min()
f3 = lambda x: x.mean() - x.min()
df2.apply(f2)
'''结果
a 6
b 6
c 6
dtype: int64
'''
除了lambda表达式还可以定义一个函数:
def f4(x):
return Series([x.min(),x.max()],index=['min','max'])
df2.apply(f4)
'''结果
a b c
min 0 1 2
max 6 7 8
'''
s1 = Series(range(4),index = ['b','d','a','c'])
s1.sort_index()
'''结果
a 2
b 0
c 3
d 1
dtype: int64
'''
s2 = Series(list([1,4,9,2]),index=['b','d','a','c'])
s2.sort_values() #默认是升序排列 若想为降序则s2.sort(ascending = False)
'''结果
b 1
c 2
d 4
a 9
dtype: int64
'''
frame = DataFrame(np.arange(8).reshape((2,4)),index = ['two','one'],columns = ['a','d','c','b'])
'''
frame
a d c b
two 0 1 2 3
one 4 5 6 7
'''
frame.sort_index()
'''
这样排序的是行的索引
a d c b
one 4 5 6 7
two 0 1 2 3
'''
frame.sort_index(axis=1)
'''
这样排序的是列的索引
a b c d
two 0 3 2 1
one 4 7 6 5
'''
obj = Series([100,80,99,54,86,12])
obj.rank()
'''
obj
0 100
1 80
2 99
3 54
4 86
5 12
dtype: int64
按从小到大排序(也就是说100是最小的)
0 6.0
1 3.0
2 5.0
3 2.0
4 4.0
5 1.0
dtype: float64
'''
obj.rank(ascending = False)
'''
按从大到小排序
0 1.0
1 4.0
2 2.0
3 5.0
4 3.0
5 6.0
dtype: float64
'''
索引是不强制唯一的
obj = Series(range(5),index = ['a','a','c','d','d'])
'''
obj
a 0
a 1
c 2
d 3
d 4
dtype: int64
'''
obj.index.is_unique
#返回false
obj.a
'''
结果
a 0
a 1
dtype: int64
'''
df = pd.read_csv('date.csv', header=None)
df.columns = ['date','number'] #重新排列csv文件中的列顺序
df['date'] = pd.to_datetime(df['date']) #将数据类型转换为日期类型
df = df.set_index('date') # 将date设置为index
s = pd.Series(df['number'], index=df.index)
#获取某几天的数据
df['2020-1-20':'2020-1-30'].head(10)
# 获取具体某天的数据,用datafrme直接选取某天时会报错,而series的数据就没有问题
df['2013-11-06']
# dataframe的truncate函数可以获取某个时期之前或之后的数据,或者某个时间区间的数据
# 但一般建议直接用切片(slice),这样更为直观,方便
#某个日期之前
print(df.truncate(after = '2013-11'))
#某个日期之后
print(df.truncate(before='2017-02'))
'''
请注意df.index的数据类型是DatetimeIndex;
df_peirod的数据类型是PeriodIndex
'''
###1、to_period()方法
#按月显示
df_period = df.to_period('M') #按月显示,但不统计 (效果就是只显示xx年xx月 不显示日)
print(type(df_period))
#按季度显示
print(df.to_period('Q').head()) #按季度显示,但不统计
#按年度显示
print(df.to_period('A').head()) #按年度显示,但不统计
###2、asfreq()方法
#按年度频率显示
df_period.index.asfreq('A') # 'A'默认是'A-DEC',其他如'A-JAN'
#按季度频率显示
df_period.index.asfreq('Q') # 'Q'默认是'Q-DEC',其他如“Q-SEP”,“Q-FEB”
#按月度频率显示
df_period.index.asfreq('M') # 按月份显示
#按工作日显示
df_period.index.asfreq('B', how='start') # 按工作日期显示
df_period.index.asfreq('B', how='end') # 按工作日期显示
#按周统计数据
print(df.resample('w').sum().head()) # “w”,week
#按月统计数据
print(df.resample('M').sum().head())# "MS"是每个月第一天为开始日期, "M"是每个月最后一天
#按季度统计数据
print(df.resample('Q').sum().head()) # "QS"是每个季度第一天为开始日期, "Q"是每个季度最后一天
#按年统计数据
print(df.resample('AS').sum())# "AS"是每年第一天为开始日期, "A是每年最后一天
#按年统计并显示
print(df.resample('AS').sum().to_period('A'))
#按季度统计并显示
print(df.resample('Q').sum().to_period('Q').head())
#按月度统计并显示
print(df.resample('M').sum().to_period('M').head())