##通常会加载以下模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
Series是pandas提供的以为数组,它类似于numpy中的Array,pandas默认会创建一个整数的索引,但也可以是字符型的索引
s = pd.Series([1,3,5,np.nan,6,8])
s
s = pd.Series([1,3,5,np.nan,6,8],[1:6]) #Series只能是一维的数组,当维数大于1时将会报错
在pandas中有一个非常常用的函数date_range,尤其是在处理时间序列数据时,这个函数的作用就是产生一个DatetimeIndex,就是时间序列数据的索引。
函数原型pandas.date_range(start=None, end=None, periods=None, freq=’D’, tz=None, normalize=False, name=None, closed=None, **kwargs)
参数:(1)start:string或datetime-like,默认值是None,表示日期的起点。
(2)end:string或datetime-like,默认值是None,表示日期的终点。
(3)periods:integer或None,默认值是None,表示你要从这个函数产生多少个日期索引值;如果是None的话,那么start和end必须不能为None。
(4)freq:string或DateOffset,默认值是’D’,表示以自然日为单位,这个参数用来指定计时单位,比如’5H’表示每隔5个小时计算一次。
(5)tz:string或None,表示时区,例如:’Asia/Hong_Kong’。
(6)normalize:bool,默认值为False,如果为True的话,那么在产生时间索引值之前会先把start和end都转化为当日的午夜0点。
(7)name:str,默认值为None,给返回的时间索引指定一个名字。
(8)closed:string或者None,默认值为None,表示start和end这个区间端点是否包含在区间内,可以有三个值,’left’表示左闭右开区间,’right’表示左开右闭区间,None表示两边都是闭区间。
返回值:DatetimeIndex
pd.date_range(start="20130104",end="20130110") #产生时间序列数据的索引
dates = pd.date_range('20130101', periods=6) #产生6个时间序列数据的索引
dates
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD')) #dataframe是一个类似表的结构,由多个Series组成,而Series在dataframe中叫做columns
df
Dataframe的行为索引index,列为labels
df2 = pd.DataFrame({ 'A' : 1.,
'B' : pd.Timestamp('20130102'),
'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
'D' : np.array([3] * 4,dtype='int32'),
'E' : pd.Categorical(["test","train","test","train"]),
'F' : 'foo' })
df2
df2.dtypes #查看dataframe中每一列的类型
df2.<TAB> #如果你用的是IPython,输入df2.按下tab键会显示以下的可选属性
# df2.A df2.bool
# df2.abs df2.boxplot
# df2.add df2.C
# df2.add_prefix df2.clip
# df2.add_suffix df2.clip_lower
# df2.align df2.clip_upper
# df2.all df2.columns
# df2.any df2.combine
# df2.append df2.combine_first
# df2.apply df2.compound
# df2.applymap df2.consolidate
# df2.D
df.head() #默认是查看数据框中的前5行
df.head(6) #可指定查看的行数
df.tail(3) #查看数据框中的后3行
df.index #查看数据框中的索引
df.columns #查看数据框中的每一列
df.values #查看df中的值
df.describe() #统计每一列的统计量,包括计数,均值,标准差,最小值,25%分位数,75%分位数,50%中位数,最大值
df.T #转置数据框
(1)索引排序
df.sort_index() #索引排序,默认axis=0,ascending=True,升序排序
df.sort_index(axis=1, ascending=False)# 对列进行排序,ascending=False 降序
(2)值排序
df.sort_values(by='B') #按列B的值从小排列到大,默认是升序
df.sort_values(by='B',ascending=False) #按B列的值从大排列到小
df.sort_values(by=["A","C"]) #按A,C列的值排列
df['A'] #选择单列,结果产生一个Series,等价于df.A
df[0:3] #通过[],对行进行切片,选择前3行.
df['20130102':'20130104'] #通过索引进行切片
有以下三种形式,
df.loc[行标签,列标签]
df.loc['a':'b'] #选取ab两行数据
df.loc[:,'one'] #选取one列的数据 df.loc的第一个参数是行标签,第二个参数为列标签(可选参数,默认为所有列标签),两个参数既可以是列表也可以是单个字符,如果两个参数都为列表则返回的是DataFrame,否则,则为Series。
dates = pd.date_range('20130101', periods=6)
dates
dates[0] #选择dates中的第一条记录
df.loc[dates[0]] #显示行索引等于2013-01-01的记录
df.loc[:,['A','B']] #选取标签为A,B的列,并且选完类型还是dataframe
df.loc['20130102',['A','B']] #显示等于20130102的A,B数据
df.loc[dates[0],'A'] #为了得到第一行第一列的值,为了得到一个标量值
df.iloc[3] #通过传递数值进行位置选择,选择的是行
df.iloc[3:5,0:2] #使用整数切片,作用与numpy/python中的情况类似
df.iloc[[1,2,4],[0,2]] #使用整数位置列表,作用和numpy/python中的情况类似
df.iloc[1:3,:] #对行进行切片,后面的:可以省略
df.iloc[1:3,] #省略后面的冒号
df.iloc[:,1:3] #对列进行切片
df.iloc[,1:3] #不可以省略前面的:
df.iloc[1,1] #获取特定的值
df.iat[1,1] #快速获取一个值,和前面的方法是等价的
df[df.A>0] #使用一个单列的值选择数据
df[df>0] #从一个dataframe中选择数据,当布尔值为真时,不满足条件的值自动显示为NaN
df2 = df.copy()# 使用isin()方法来过滤数据
df2['E'] = ['one','one','two','three','four','three']
df2
df2[df2['E'].isin(['two','four'])] #选取E列中为'two','four'的数据
df2['E'].isin(['two','four']) #返回一列的布尔值
(1)设置一个新列会自动将数据和索引对齐.
Series是pandas模块提供的一种一维的数组,它类似numpy中的Array,但是有一些特殊的功能。pandas的数据结构都会包含索引。索引可以是数字,也可以是字符
s1 = pd.Series([1,2,3,4,5,6],index = pd.date_range('20130102',periods=6))
s1 #创建一个Series
df['F'] = s1 #将s1赋值给df中的F列
df
(2)通过标签来设置值
df.at[dates[0],'A'] = 0 #将df中的第一行第一列的值设置为0
df
(3)通过numpy array重新给一列赋值
df.loc[:,'D'] = np.array([5]*len(df)) #将D列的值全部赋值为5
df
(4)通过where操作来设置新值
df2 = df.copy()
df2[df2>0] = -df2 #在所有大于0的值前面加上负号
df2
pandas主要是使用值np.nan来代替缺失数据,默认情况下是不包含在计算中。
df1 = df.reindex(index=dates[0:4],columns=list(df.columns)+['E'])
df1
df1.loc[dates[0]:dates[1],'E'] = 1
df1
df1.dropna(how='any') #删除任何有缺失值的行
df1.fillna(value=5) #用5来代替所有的缺失值
pd.isna(df1)
操作一般不包括缺失值
(1)进行描述性统计
df.mean() #求每一列的均值,参数为轴,可选0或1,默认情况下为0,即按照列运算
(2)对另一轴进行同样的操作
df.mean(1) #对每一行求均值
(3)对具有不同维度的对象进行操作需要对齐。此外,pandas会对指定的对象自动broadcasts
s = pd.Series([1,3,5,np.nan,6,8],index=dates).shift(-2) #shift函数用来控制值前移还是后移,当小于0时表示前移
s
s = pd.Series([1,3,5,np.nan,6,8],index=dates).shift(2) #表示将值向后移动2个单位,缺少的值用NAN填充
s
df.sub(s,axis='index')
对数据应用函数
df
df.apply(np.cumsum) #对df数据框中的每一列累计求和
df.apply(lambda x:x.max()-x.min()) #lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边的返回值。
s = pd.Series(np.random.randint(0,7,size=10)) #从0到7中随机抽取10个整数
s
s.value_counts() #对s中的值计数
Series在str属性中配置了一系列的字符串处理方法,使得其更加容易对数组中的每一个元素进行操作
s = pd.Series(['A','B','C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
s.str.lower() #对s中的字符串全部转换为小写
pandas提供了各种各样的设施,使得可以很容易组合Series,Dataframe和pandas对象
df = pd.DataFrame(np.random.randn(10,4)) #创建10行4列的dataframe
df
pieces = [df[:3],df[3:7],df[7:]] #break it into pieces
pieces
pd.concat(pieces) #合并个列
(1)类似SQL风格的合并
left = pd.DataFrame({'key':['foo','foo'],'lval':[1,2]})
right = pd.DataFrame({'key':['foo','foo'],'rval':[4,5]})
left
right
pd.merge(left,right,on='key') #根据key关键词合并数据,一个key有多个值
(2)另外的一个实例
left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4, 5]})
left
right
pd.merge(left, right, on='key')
将行追加到数据框中
df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
df
s = df.iloc[3] #选择dataframe中索引为3的行
s
df.append(s, ignore_index=True) #将s插入到df中的尾部,忽略本身的索引
df.append(s, ignore_index=False) #使用本身的索引
对于”group by”操作,我们通常是指以下一个或多个操作步骤:
(Splitting)按照一些规则将数据分为不同的组;
(Applying)对于每组数据分别执行一个函数;
(Combining)将结果组合到一个数据结构中;
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
....: 'foo', 'bar', 'foo', 'foo'],
....: 'B' : ['one', 'one', 'two', 'three',
....: 'two', 'two', 'one', 'three'],
....: 'C' : np.random.randn(8),
....: 'D' : np.random.randn(8)})
df
df.groupby('A').sum() #根据A组的取值分组,然后对每一组求平均值
df.groupby(['A','B']).sum()
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zipped = zip(a,b)
list(zipped) #将对象中对应的元素打包成一个个元组,
list(zip(a,c)) #如果各个迭代器的元素个数不一致,则返回的列表与最短的对象相同
zip(*zipped) ## 与 zip 相反,可理解为解压,返回二维矩阵式
for i in zipped
print i
tuples = list(zip(*[['bar', 'bar', 'baz', 'baz',
....: 'foo', 'foo', 'qux', 'qux'],
....: ['one', 'two', 'one', 'two',
....: 'one', 'two', 'one', 'two']])) #将两列合并
tuples #显示合并后的数据
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) #运用MultiIndex.from_tuples可以生成对应的索引和水平位置
index
df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B'])
df
df2 = df[:4]
df2
stacked = df2.stack()
stacked
stacked.unstack()#解压最后一层
stacked.unstack(1)#解压第二层
stacked.unstack(2) #解压第3层
stacked.unstack(0)#解压第一层
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
.....: 'B' : ['A', 'B', 'C'] * 4,
.....: 'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
.....: 'D' : np.random.randn(12),
.....: 'E' : np.random.randn(12)})
df
pd.pivot_table(df,values='D',index=['A','B'],columns=['C']) #索引为A,B,列为C,选用D中的值
pandas 拥有简单,强大,高效的函数用来处理频率转换中的重采样问题(例如将秒数据转换为5分钟数据)
rng = pd.date_range('1/1/2012', periods=100, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
ts.resample('5Min').sum()
rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D')
ts = pd.Series(np.random.randn(len(rng)), rng)
ts
ts_utc = ts.tz_localize('UTC')
ts_utc
ts_utc.tz_convert('US/Eastern')
rng = pd.date_range('1/1/2012', periods=5, freq='M')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts
ps = ts.to_period()
ps
ps.to_timestamp()
prng = pd.period_range('1990Q1', '2000Q4', freq='Q-NOV')
ts = pd.Series(np.random.randn(len(prng)), prng)
ts.index = (prng.asfreq('M', 'e') + 1).asfreq('H', 's') + 9
ts.head()
pandas的dataframe可以包含categorical类型的数据
df = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']})
df
df['grade'] = df['raw_grade'].astype('category') #将数据转换成分类数据
df['grade']
df['grade'].cat.categories = ['very good','good','very bad'] #给grade中的值重命名
df
df["grade"] = df["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"])
df["grade"]
df.sort_values(by='grade')
df.groupby('grade').size()
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
ts.plot()
df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index,
.....: columns=['A', 'B', 'C', 'D'])
df = df.cumsum()
plt.figure(); df.plot(); plt.legend(loc='best')
df.to_csv('foo.csv') #df为存储数据的源文件,foo为读出的csv文件的命名
foo = pd.read_csv('foo.csv') #从电脑中读入一个csv文件
foo.head(6) #查看foo文件中的前6行
df.to_hdf('foo.h5','df')
foo= pd.read_hdf('foo.h5','df')
foo.head()
df.to_excel('foo.xlsx', sheet_name='Sheet1') #foo为工作簿名,Sheet1为表名称
foo = pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
foo.head()