pandas基于numpy实现,可以进行一系列数据分析
import pandas as pd
df =pd.read_csv("lol.csv", header=0)
df.head()
# 从 csv 文件读取数据
pd.read_csv('foo.csv')
# 保存到 csv 文件
df.to_csv('foo.csv')
# 读取 excel 文件
pd.read_excel('foo.xlsx','Sheet1', index_col=None, na_values=['NA'])
# 保存到 excel 文件
df.to_excel('foo.xlsx', sheet_name='Sheet1')
Series由一组数据及与之相关索引组成
series对象以及索引都有一个名字属性,.name
#创建日期索引序列
dates =pd.date_range('20130101', periods=6)
#DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
# '2013-01-05', '2013-01-06'], dtype='datetime64[ns]', freq='D')
index应与列表长度一致
s = pd.Series([1,5,8,9], index=['a','b','c','d'])
s = pd.Series(10, index=['a','b','c'])
s = pd.Series({'a':12, 'b':6, 'c':8},index=['a','b','c','d','e'])
s = pd.Series(np.arange(5), index=np.arange(4,9))
s.index 获得索引
s.values 获得数据
s.value_counts() 统计每个数据出现次数
s.str.lower() 将每个字符全部变为小写
自定义索引和自动索引(从0开始编号)并存,但不能混合使用
Series操作类似ndarray类型
Series操作类似字典类型
Series类型对齐操作
s1 = pd.Series([2,5,9], ['a','b','c'])
s2 = pd.Series([2,5,3,4,7], ['b','c','d','a','f'])
s3 = s1+s2
print(s3)
#a 6.0
#b 7.0
#c 14.0
#d NaN
#f NaN
#dtype: float64
对齐会将共有索引数据执行操作,不共有索引会将没有的赋值为NaN再运算,即运算结果为NaN
行索引:index,axis=0
列索引:column,axis=1
d = pd.DataFrame(np.arange(10).reshape(2,5))
#会自动生成行列索引
dt = {'one':pd.Series([1,5,9], index=['a','b','c']), 'two':pd.Series([8,9,2,5], index=['a','b','c','d'])}
d = pd.DataFrame(dt)
#根据index的并集生成,若一部分series没有相应index,则其值为NaN
d1 = {'one':[2,5,4,6],'two':[5,2,1,7]}
d2 = pd.DataFrame(d1, index=['a','b','c','d'])
df =pd.DataFrame(np.random.randn(6,2), list('abcdef'), columns=['one', 'two'])
one two
a -0.752108 -0.440572
b 0.431561 0.337005
c 0.768852 -0.428917
d -0.882925 1.241001
e 0.701973 1.568184
f -0.375796 0.595974
索引:
切片
d[0:] :第0行即之后的行
d[2:5]:第二行到第五行,不包含第五行
d[行索引1:行索引2]:
知道行列索引名字时可以使用loc
行列索引不知道,或者不便于输入使用iloc(完全用数字定位)
df.T 转置
pd.concat(objs,axis=0,join=‘outer’) :将多个pandas对象连接
--------- objs为列表、[df1,df2,df3,…dfn]
df.append(df[0], ignore_index=True) :在df后追加行
重新索引(即改变原索引)
d.reindex(index=None, columns=None, ...)
index, columns | 新的行列自定义索引 |
fill_value | 重新索引时,用于填充NaN的值 |
method | 填充方法,ffill当前值向前填充,bfill向后填充 |
limit | 最大填充量 |
copy | 默认True,生成新对象,False时,新旧相等不复制 |
Series和DataFrame的索引是Index类型,Index对象是不可修改类型
.append(index) | 连接另一个index对象,产生新的index对象,即追加行 |
.diff(periods,axis) | 计算一阶差分, |
.intersection(index) | 计算交集 |
.union(index) | 计算并集 |
.delect(loc) | 删除loc位置处元素 |
.insert(loc,e) | 在loc位置处插入元素e |
.add(d, **argws) | 类型间加法运算,可选参数 |
.sub(d, **argws) | 类型间减法运算,可选参数 |
.mul(d, **argws) | 类型间乘法运算,可选参数 |
.div(d, **argws) | 类型间除法运算,可选参数 |
根据索引在指定轴排序,默认升序
d.sort_index(axis=0, ascending=True)
在指定轴根据数据的大小排序,默认升序
Series.sort_values(axis=0, ascending=True)
DataFrame.sort_values(by, axis=0, ascending=True)
by:axis轴方向上某个索引或索引列表
不管升序还是降序,NaN同一放到末尾
Series,DataFrame通用
df. | ---- |
---|---|
.sum(axis) | 计算数据的总和,按0轴计算,下同 |
.count(axis) | 非NaN值数量 |
.mean(axis) .median(axis) | 数据的算术平均数,算术中位数 |
.var(axis) .std(axis) | 数据的方差,标准差 |
.quantile(q,axis) | 计算数据分位数,q范围为0~1 |
.mad(axis) | 根据平均值计算平均绝对离差 |
skew(axis) | 计算数据偏度(三阶矩) |
kurt(axis) | 计算数据峰度(四阶矩) |
.min(axis) .max(axis) | 数据最大最小值 |
.idxmin(axis=0) .inxmax(axis=0) | 计算数据最大最小值所在位置的索引(自定义索引) |
.describe() | 针对0轴各列的统计汇总(包含count,mean,std,min,25%,50%,75%,max)(返回Sreies对象或DataFrame对象) |
累计统计分析
.cumsum(axis=0) | 依次给出前n个数的和,即依次累加 |
.cumprod(axis=0) | 依次给出前n个数的乘积 |
.cummax(axis=0) | 依次给出前n个数的最大值 |
.cummin(axis=0) | 依次给出前n个数的最小值 |
.rolling(w,axis=0).sum() | 依次计算相邻w个元素的和 |
.rolling(w,axis=0).mean() | 依次计算相邻w个元素的算术平均值 |
.rolling(w,axis=0).var() | 依次计算相邻w个元素的方差 |
.rolling(w,axis=0).std() | 依次计算相邻w个元素的标准差 |
.rolling(w,axis=0).min() .max() | 依次计算相邻w个元素的最大最小值 |
相关分析
.cov() | 计算协方差矩阵,series时要s1.cov(s2),dataframe计算其各列相关性,下同 |
.corr() | 计算相关系数矩阵,pearson,spearman,kendall等系数 |
协方差 > 0,正相关
协方差 < 0,负相关
协方差 = 0,独立无关
相关系数
0.8-1.0:极强相关
0.6-0.8:强相关
0.4-0.6:中等程度相关
0.2-0.4:弱相关
0.0-0.2:极弱相关或无相关
df.head(n) 显示开头n行数据
df.tail(n) 显示末尾n行数据
df[列名].count() 统计非nan值数量
df.values 数据的numpy ndarray对象
df[‘a’].value_counts() : 统计’a’列各个元素值出现的次数
df.info() 数据的行列基本信息
df.isna() df.isnull():判断元素是否为空值,nan值,返回df一样大小的数据,bool类型
df.notna() df.notnull():判断元素是否不是空值,nan值,返回df一样大小的数据,bool类型
函数原型:
pivot_table(data, values=None, index=None, columns=None, aggfunc=‘mean’, fill_value=None, margins=False, dropna=True, margins_name=‘All’)
df =pd.DataFrame({'A': ['one','two','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)})
#生成数据透视表
table = pd.pivot_table(df, values='E', index=['A','B'], columns=['C'])
df1 = df2.copy() :复制数组
修改数据可以通过重新给数据赋值:df[‘a’] = df_1[‘a’]
drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors=‘raise’):删除指定轴的指定行或列,不改变原对象
删除或者填充缺省项
函数原型:
dropna(axis=0, how=‘any’, thresh=None, subset=None, inplace=False)
#删除所有带有缺省项的行
df1.dropna(how='any')
#根据指定列删除
df1.dropna(subset=['a'])
#填充缺省项
df1.fillna(value=5)
布尔(bool)索引选择数据
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(1,10,24).reshape(6,4),columns=list('abcd'))
# df:
# a b c d
#0 8 6 7 6
#1 9 4 4 2
#2 7 7 1 3
#3 1 2 8 4
#4 8 3 8 6
#5 6 9 9 4
#选择df['b']>4的那些列数据
df[df['b'] > 4]
# a b c d
#0 8 6 7 6
#2 7 7 1 3
#5 6 9 9 4
函数原型:groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)
代表运算的字符串包括‘sum’、‘mean’、‘min’、‘max’、‘count’
df1 = df.groupby('one').sum()
#one,two为列名
df2 = df.groupby(['one','two']).sum()
将int,float改为时间格式(datatime)
#将领券日期改为时间格式
offline['Date_received'] = pd.to_datetime(offline['Date_received'],format='%Y%m%d')
#pd.to_datetime(19911204,format='%Y%m%d')
#Timestamp('1991-12-04 00:00:00')
创建时间序列
rng =pd.date_range('1/1/2012 00:00', periods=100, freq='S')
# periods:周期 freq:‘S’以秒为周期增加 'D':以天,默认为一天 'Y':以年,默认1年
通过datatime时间格式得到月份,星期值
##添加领券时间为周几属性
#offline['weekday_received'] = list(map(lambda x : x.isoweekday(), offline['Date_received']))
##添加领券时间为几月
#offline['month_received'] = list(map(lambda x : x.month, offline['Date_received']))
##添加消费时间为周几属性
Series 和 DataFrame 对象的方法中,凡是会对数组作出修改并返回一个新数组的,往往都有一个 replace=False 的可选参数。如果手动设定为 True,那么原数组就可以被替换。
条形图和横向条形图
df2.plot.bar()
df2.plot.bar(stacked=True) #是否堆叠
df2.plot.barh(stacked=True) #横向展示
df4 = pd.DataFrame({'a': np.random.randn(1000) + 1, 'b': np.random.randn(1000),
'c': np.random.randn(1000) - 1}, columns=['a', 'b', 'c'])
df4.plot.hist(alpha=0.5)
#透明度为0.5,0-1,0完全透明,1完全不透明
df4.plot.hist(stacked=True, bins=20)
#几个列的元素叠加展示,柱形个数为20
df4['a'].plot.hist(orientation='horizontal', cumulative=True)
#横向展示并且累加
df['A'].diff().hist()
df.diff().hist(color='k', alpha=0.5, bins=50)
data = pd.Series(np.random.randn(1000))
data.hist(by=np.random.randint(0, 4, 1000), figsize=(6, 4))
#分组,将by与data对应,by数据相同的作为一个分组
df = pd.DataFrame(np.random.rand(10, 5), columns=['A', 'B', 'C', 'D', 'E'])
df.plot.box()
#s.plot.box() #series类型箱线图
color = {'boxes': 'DarkGreen', 'whiskers': 'DarkOrange','medians': 'DarkBlue', 'caps': 'Gray'}
#设置箱体,1/2处,线以及上下最低点颜色
df.plot.box(color=color, sym='r+')
#异常点标记为红色+
df.plot.box(vert=False, positions=[1, 4, 5, 6, 8])
#横向,以及给出各个箱线图纵坐标位置为1,4,5,6,8
df.boxplot() #给出刻度延长线
df = pd.DataFrame(np.random.rand(10, 2), columns=['Col1', 'Col2'])
df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'])
plt.figure();
bp = df.boxplot(by='X') #根据X中分组,绘制col1,col2箱线图
df = pd.DataFrame(np.random.rand(10, 3), columns=['Col1', 'Col2', 'Col3'])
df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'])
df['Y'] = pd.Series(['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'])
plt.figure();
bp = df.boxplot(column=['Col1', 'Col2'], by=['X', 'Y'])
#根据X,Y中分组,绘制行索引为col1和col2的箱线图
bp = df.groupby('X').boxplot()
#根据X中的分组,绘制X中分组A和B的箱线图,以col1,col2,col3为横坐标
面积图
df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
df.plot.area() #stacked默认为True,堆叠
df.plot.area(stacked=False)
df = pd.DataFrame(np.random.rand(50, 4), columns=['a', 'b', 'c', 'd'])
df.plot.scatter(x='a', y='b') #必须为列索引或者列索引的自动索引数字
ax = df.plot.scatter(x='a', y='b', color='DarkBlue', label='Group 1')
df.plot.scatter(x='c', y='d', color='DarkGreen', label='Group 2', ax=ax)
#ax=ax在同一个图绘制图形
df.plot.scatter(x='a', y='b', c='c', s=50) #s设置点的大小,c表示根据‘c'列大小渐进色绘制
df.plot.scatter(x='a', y='b', s=df['c'] * 200)
# 根据c列大小绘制不同点的大小
series = pd.Series(3 * np.random.rand(4), index=['a', 'b', 'c', 'd'], name='series')
series.plot.pie(figsize=(6, 6))
df = pd.DataFrame(3 * np.random.rand(4, 2), index=['a', 'b', 'c', 'd'], columns=['x', 'y'])
df.plot.pie(subplots=True, figsize=(8, 4))
series.plot.pie(labels=['AA', 'BB', 'CC', 'DD'], colors=['r', 'g', 'b', 'c'], autopct='%.2f', fontsize=20, figsize=(6, 6))
#设置标签,颜色,百分百表示,字体大小,窗口大小
series = pd.Series([0.1] * 4, index=['a', 'b', 'c', 'd'], name='series2')
series.plot.pie(figsize=(6, 6))
#如果数字的总和小于1,则会画一个不完整的圆
数据分步密度图(density plot)
ser = pd.Series(np.random.randn(1000))
ser.plot.kde()
ser.plot.density()
一些特殊操作
df.plot(subplots=True, figsize=(6, 6))
#将每个图形画在不同子图中
df.plot(subplots=True, layout=(2, 3), figsize=(6, 6), sharex=False)
#Layout布局为两行三列,sharex:将lengend放在合适地方
表格的绘制
fig, ax = plt.subplots(1, 1)
df = pd.DataFrame(np.random.rand(5, 3), columns=['a', 'b', 'c'])
df.plot(table=True, ax=ax) #绘制表格
df.plot(table=np.round(df.T, 2), ax=ax) #四舍五入保留小数点两位
from pandas.plotting import table
fig, ax = plt.subplots(1, 1)
table(ax, np.round(df.describe(), 2), loc='upper right', colWidths=[0.2, 0.2, 0.2])
#将基本数据显示在右上方,colWidths横向占绘图区域的比例
df.plot(ax=ax, ylim=(0, 2), legend=None)