Pandas 学习笔记
在使用之前,需要导入pandas库
import pandas as pd
导入数据
常用方法
pd.DataFrame() # 自己创建数据库,用于练习
pd.read_csv(filename, sep=',', names=[]) # 从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表格
从 excel 导入数据
xls_file = pd.ExcelFile(path)
print(xls_file.sheet_names)
df = xls_file.parse(sheet_name)
从 csv 导入数据
df = pd.read_csv(path, sep=',', names=[])
从 mysql 导入数据
import pymysql
conn = pymysql.connect(host='', database='', user='', passwd='', port=3306)
df = pd.read_sql('select * from table', con=conn)
导出数据
df.to_csv(filename) #导出数据到CSV文件
df.to_excel(filename) #导出数据到Excel文件
df.to_sql(table_name, connection_object) #导出数据到SQL表
df.to_json(filename) #以Json格式导出数据到文本文件
with pd.ExcelWriter('test.xlsx', index=False) as writer:
df1.to_excel(writer, sheet_name='单位1')
df2.to_excel(writer, sheet_name='单位2')
数据表信息查看
维度查看
df.shape
数据表基本信息
df.info()
每一列数据的格式
df.dtypes
某一列格式
df['b'].dtype
空值
df.isnull()
某一列的空值
df['b'].isnull()
某一列的唯一值
df['b'].unique()
查看数据表的值
df.values
查看列名称
df.columns
查看前10行、后10行数据
df.head()
df.tail()
数据表清洗
用数字 0 填充空值
df.fillna(value=0)
使用列 price 的均值对 NA 进行填充
df['price'].fillna(df['price'].mean())
清除 title 字段的字符空格
df['title'] = df['title'].map(str.strip)
大小写转换
df['title'] = df['title'].str.lower()
更改数据格式
df['price'].astype('int|float')
更改列名称
df.rename(columns={'category': 'category-new'})
删除后出现的重复值
df['city'].drop_duplicates(subset=['field'])
删除先出现的重复值
df['city'].drop_duplicates(keep='last')
数据替换
df['city'].replace('sh', 'shanghai')
如果 price 列的值 >3000,group 列显示 high,否则显示 low
df['group'] = np.where(df['price'] > 3000, 'high', 'low')
对符合多个条件的数据进行分组标记
df.loc[(df['city'] == 'beijing') & (df['price'] >= 4000), 'sign'] = 1
将完成分裂后的数据表和原 df_inner 数据表进行匹配
df_inner = pd.merge(df_inner, split, right_index=True, left_index=True)
数据提取
按索引提取单行的数据
df.loc[3]
按索引提取区域行数据
df.iloc[0:5]
重设索引
df.reset_index()
设置日期为索引
df = df.set_index('date')
提取4日之前的所有数据
df[:'2020-09-04']
使用 iloc 按位置区域提取数据
#冒号前后的数字不再是索引的标签名称,而是数据所在的位置,从0开始,前三行,前两列
df.iloc[:3, :2]
使用 iloc 按位置单独提取数据
#提取第0、2、5行,4、5列
df.iloc[[0,2,5],[4,5]]
使用 ix 按索引标签和位置混合提取数据
#提取2020-09-03之前,前四列数据
df.ix[:'2020-09-03',:4]
判断 city 列的值是否为北京
df['city'].isin(['beijing'])
判断 city 列里是否包含 beijing 和 shanghai,然后将符合条件的数据提取出来
df.loc[df['city'].isin(['beijing','shanghai'])]
提取前三个字符,并生成数据表
pd.DataFrame(category.str[:3])
数据筛选
使用与、或、非三个条件配合大于、小于、等于对数据进行筛选,并进行计数和求和。
使用『与』进行筛选
df.loc[(df['age'] > 25) & (df['city'] == 'beijing'), ['id','city','age','category','gender']]
使用『或』进行筛选
df.loc[(df['age'] > 25) | (df['city'] == 'beijing'), ['id','city','age','category','gender']]
使用『非』进行筛选
df.loc[(df['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id'])
对筛选后的数据按 city 列进行计数
df.loc[(df['city'] != 'beijing'), ['id','city','age','category','gender']].city.count()
使用 query 函数进行筛选
df.query('city == ["beijing","shanghai"]')
对筛选后的结果按 price 进行求和
df.query('city == ["beijing","shanghai"]').price.sum()
数据汇总
主要函数 groupby 和 pivote_table
对所有的列进行计数汇总
df.groupby('city').count()
按城市对 id 字段进行计数
df.groupby('city')['id'].count()
对两个字段进行汇总计数
df.groupby(['city','size'])['id'].count()
对 city 字段进行汇总,并分别计算 price 的合计和均值
df.groupby('city')['price'].agg([len,np.sum,np.mean])
df.groupby('district')['avg_price'].agg([('avg', 'mean'), ('num', 'count')])
分组计算与排序
df.groupby('district')['avg_price'].agg([('avg', 'mean'), ('num', 'count')]).sort_values(by='num', ascending=False)
数据统计
数据采样,计算标准差,协方差和相关系数
简单的数据采样
df.sample(n=3)
手动设置采样权重
weights = [0, 0, 0, 0, 0.5, 0.5]
df.sample(n=2, weights=weights)
采样后不放回
df.sample(n=6, replace=False)
采样后放回
df.sample(n=6, replace=True)
数据表描述性统计
#round函数设置显示小数位,T表示转置
df.describe().round(2).T
计算列的标准差
df['price'].std()
计算两个字段的协方差
df['price'].cov(df['m-point'])
数据中所有字段间的协方差
df.cov()
两个字段的相关性分析
df['price'].corr(df['m-point'])
#查看基本统计信息
df.columnname.describe()
#数据表基本信息
#查看数据集大小
df.shape
#查看唯一值
df['columnname'].unique()
df['columnname'].nunique()
DataFrame
#复制表,deep为False是引用,修改数据会影响源数据
newdf = df.copy(deep=True)
#查看数据是否重复
df.duplicated()
#设置索引
keys = pd.to_datetime(df.loc[:, 'datetime'])
df.set_index(keys, inplace=True)
#重新采样,支持datetime类型的索引
df.resample('1A').sum()
遍历 Series 的元素
df['A'].apply(lambda x: 111 if x <= 3 else 999)
列操作
#打印所有列名
print(df.columns.values)
#修改列名
df.rename(columns={df.columns[2]:'new name'}, inplace=True)
df = df.rename(columns={'old name':'new name'}, inplace=True)
df.columns = ['col 1', 'col 2']
#修改列的序顺
df.reindex(columns=['col 1', 'col3', 'col2'])
行操作
#axis需要合并的轴,0为行,1为列
pd.concat([df1, df2], join='outer', axis=0)
分组计算与排序
grouped = df.groupby(列名)
grouped[列名].count()
gdf = grouped.size().reset_index(name='total')
grouped = df.groupby(列名).sum().reset_index()
grouped.sort_values(列名, ascending=False)
#按key1分组,计算data1列的平均值
key1 = df['data1'].groupby(df['key1']).mean()
#语法糖为
key1 = df.groupby(['key1'])['data1'].mean()
#按范围分组
bins = pd.cut(df['columnname'], [0, 100, 250, 1000])
df.groupby(bins)['columnname'].agg(['count', 'sum'])
选择列
#选择一列
df['columnname']
#选择多列
data[['column1','column2']]
查询与过滤
#返回DataFrame
df.query("col1 == col2")
df.loc[df.col == val]
df.loc[df.col.isin([1,2,3])]
#Where条件过滤
df[df.col > condition]
#where多条件过滤
df[(df.col >= 50) & (df.col <= 100)]
#删除重复行
df.drop_duplicates([字段名], inplace=True)
newdf = df.drop_duplicates(['column'])
处理缺失数据
#添加默认值,将NaN用空字符串替换
df.country = df.country.fillna('')
#删除任何包含NA值的行
df.dropna()
#删除一整行的值都为NA
df.dropna(how='all')
#一行中有多少非空值的数据才可以保留
df.drop(thresh=5)
#指定检查的列
df.dropna(subset=['title_year'])
#删除不完整的列
df.drop(axis=1, how='all')
df.drop(axis=1, how='any')
清洗转换数据
#只保留符合规则的数据,其它的以NaN替代
extr = df['columnname'].str.extract(r'^(\d{4})', expand=False)
extr.head()
df['columnname'].astype('int|float')
#转换日期
df.loc[:,'columnname'] = pd.to_datetime(df.loc[:,'columnname'], format='%Y-%m-%d', errors='coerce')
#日期字段操作
df['datetime'].dt.year #获取日期年份
可视化
#直方图
df.hist('columnname', bins=15, grid=False)
#柱状图
df.plot.bar()
df.plot.barh(figsize=(12,8)) #水平方向
#柱状图上画平均线
c = np.mean(df.col)
plt.axhline(y=c, color='red')
#自定义x轴名称
ax = df.plot(kind='bar', figsize=(15,10))
x_labels = grouped.index.map(lambda x : '{}楼'.format(int(x)))
ax.set_xticklabels(x_labels)
#散点图
df.plot.scatter(x='columnname', y='columnname')
#箱线图
df['columnname'].plot.box(figsize=(15,10))