Pandas简介
Pandas是python数据分析中一个非常核心的数据库, 在日常的工作中经常需要使用Pandas库来对数据进行处理分析。Pandas的核心为两大数据结构, Series和DataFrame,Series用于存储一维数据, 而DataFrame存储多维数据。
常用的软件
Anaconda是数据分析中运行python的一款利器, 安装教程可参考
Anaconda入门使用指南
Series对象
Series用于存储一维数据,由两个相互关联的数组组成, 主数组用来存放数据。主数据每个元素都有一个与之关联的标签,这些标签存储在另一个叫Index的数组中。
- 创建Series对象
zy = pd.Series([2, 3, 4, 6, 7, 4], index = ['a', 'b', 'c', 'd', 'e', 'f'])
- 查看Series对象的两个数组
# 查看元素
zy.values
# 查看索引
zy.index
- 查看元素
# 将zy看做Numpy数组,智定键
zy[2]
zy[0:2]
# 指定标签
zy['c']
zy[['b', 'c']]
- 筛选元素
zy[zy >3]
- 查看组成元素
# 查看包含的不同元素
zy.unique()
zy.value_counts()
- 通过字典来创建
zy=Series({'a':1,'b':2,'c':3})
DataFrame对象
读取与写入Excel数据
- 读取文件夹的内容
import pandas as pd
import numpy as np
from pandas import Series, DataFrame
import os
file_list = os.listdir(r'E:\工作文件\周报\周数据\测试\0902-0908')
print(file_list, '\t')
- 读取xls格式Excel表
df = pd.read_excel('E:/工作文件/周报/周数据/测试/0902-0908/an-商品汇总-uv.xls')
df = pd.read_excel(r'E:\工作文件\周报\周数据\测试\0902-0908\an-商品汇总-uv.xls')
- 读取csv格式Excel表
df = pd.read_csv('E:/工作文件/周报/周数据/测试/0902-0908/商品汇总.scsv')
- 读取txt格式数据
df = pd.read_table(r'C:\Users\Administrator\Desktop\haha.txt')
with open(r'C:\Users\Administrator\Desktop\haha.txt', 'r') as f:
df = f.readlines()
df = np.loadtxt(r'C:\Users\Administrator\Desktop\haha.txt') # 将txt文件存为numpy数组
- 将数据写入Excel表, 并输出
data.to_excel('C:/Users/Administrator/Desktop/'+'商品分类.xlsx')
data.to_excel(r'C:\Users\Administrator\Desktop\\'+'商品分类.xlsx')
data.to_excel(r'C:\Users\Administrator\Desktop/'+'商品分类.xlsx')
- 其他数据格式
# 从SQL表/库导入数据
pd.read_sql(query, connection_object)
# 从JSON格式的字符串导入数据
pd.read_json(json_string)
# 解析URL、字符串或者HTML文件,抽取其中的tables表格
pd.read_html(url)
# 从你的粘贴板获取内容,并传给read_table()
pd.read_clipboard()
# 从字典对象导入数据,Key是列名,Value是数据
pd.DataFrame(dict)
# 导出数据到SQL表
df.to_sql(table_name, connection_object)
# 以Json格式导出数据到文本文件
df.to_json(filename)
描述数据
- 表信息
df.info()
- 显示数据的行列数
df.shape
- 查看数据格式dtpyes
df.dtypes
- 显示列名、元素
df.columns
df.values
- 添加默认列名
# 如果数据没有标题行,可用pandas添加默认的列名
df = pd.read_excel('x.xlsx', header = None)
- 显示前数据前5行
df.head(5)
df[['标题', '客户端uv']].head()
- 显示数据后5行
df.tail(5)
- 值
df.values
- 读取a列
df['a']
- 修改索引
df = df.set_index['标题']
- 显示数据唯一值(unique函数)
# 数据有0, 是因对缺失值进行了填充
df['经纪人级别'].unique()
- 对第几行数据不读取
#不读取哪里数据,可用skiprows=[i],跳过文件的第i行不读取
df = pd.read_excel('x.xlsx',skiprows=[2] )
- 对缺失值进行识别
# 所有缺失值显示为True
pd.insull(df) # df.isnull()
- 计算
#计算此data的数量
df['data'].value_counts()
# 升序计数
df['data'].value_counts(ascending = True)
# 升序计数并分组
df['data'].value_counts(ascending = True, bins = 2)
# 计数
df['data'].count()
数据清洗
- 删除空值 (dropna函数)
df.dropna(how='any')
- 填充空值(fillna函数)
# 空值用0填充
df.fillna(value=0)
# 用均值对空值进行填充
df['经纪人响应时长'].fillna(df['经纪人响应时长'].mean())
- 更改数据格式
# 将数据格式int64,改为float格式
df['大区'].astype('float64')
- 更改列名称
df.rename(columns={'IM渠道': '渠道'})
- 找到重复值
df.duplicated()
- 删除重复值
# 默认第一次出现的保留,其余删除
df['门店'].drop_duplicates()
最后一次出现的保留,其余删除
df['门店'].drop_duplicates(keep = 'last')
- 对列表内的值进行替换
df['客户UCID'].replace('10531975', '110')
- 找出异常值
print(data.describe())
# 对异常值进行删除
- 修改数据
# 修改结果
df.replace(参数)
# 修改索引
df.rename(参数)
# 增加
df.append(参数)
# 删除
def df['a']
df.drop(['a', 'b'], inplace = True)
对数据进行处理
- 对两个数据进行合并- mearge, join, concat函数
# 按照轴把多个对象拼接起来
pd.concat(df1, df2)
# join函数适合根据索引进行合并,合并索引相同但列不同的对象
# merge函数,根据一个或多个键连接多行
left = pd.DataFrame({'key':['ko','k1','k2','k3'],
'key2' : ['ko','k1','k2','k3'],
'A' :['ao','a1','a2','a3' ],
'B' : ['bo','b1','b2','b3' ]})
right =pd.DataFrame({'key':['ko','k1','k2','k3'],
'key2' : ['ko','k1','k2','k4'],
'c' :['co','c1','c2','c3' ],
'd' : ['do','d1','d2','d3' ]})
# 将left和right进行合并
pd.merge(left, right)
# 指定以key为键进行合并
pd.merge(left, right, on = 'key')
# key2列不相同的部分会直接舍弃掉
pd.merge(left, right, on = ['key', 'key2'])
# 保留key2列不相同的部分
pd.merge(left, right, on = ['key', 'key2'], how = 'outer')
# 不相同的部分指定以左表为基准
pd.merge(left, right, on = ['key', 'key2'], how = 'left')
- 对数据进行排序
data =pd.DataFrame({ 'group':['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a'],
'data' : [4, 2, 5, 6, 7, 8, 2, 9, 4]})
# 在保证group列降序的情况下,对data列进行升序处理
data.sort_values(by = ['group', 'data'],ascending = [False, True], inplace = True)
- 对数据进行分组——excel中的数据透视表
# 如果price列的值>3000,group列显示high,否则显示low
df['group'] = np.where(df['客户当天发送消息数'] > 5,'high','low')
# 对符合多个条件进行分组
# 符合经纪人级别为A1且经纪人响应时长>24的在sign列显示为1
df.loc[(df['经纪人级别'] == 'A1') & (df['经纪人响应时长']>= 24.0), 'sign']=1
- 对数据进行分列
pd.DataFrame((x.split('网') for x in df['客户注册渠道']),
index=df.index,columns=['客户注册渠道','size'])
- 新增一列
data = data.assign(ration = [4, 2, 5, 6, 7, 8, 2, 9, 4])
data['rations'] = [5, 2, 5, 6, 7, 8, 2, 9, 4]
- 对数据进行切分
bins = [1,3,6,9]
data_cut = pd.cut(data['data'], bins)
对数据进行提取,筛选
df = pd.DataFrame({'A':[7,8,9,20, 10, 11, 14, 13, 14],
'B' : [1,2,3,4,5, 6, 7, 7, 8]})
- 按条件进行提取
# 选出B列的值大于3的数
df[df['B']>3]
# 当 A列的值大于13时, 显示B,c列的值
df[['B','C']][df['A']>13]
# 用isin函数进行判断
# 使用isin函数根据特定值筛选记录。筛选A值等于10或者13的记录
df[df.A.isin((10, 13))]
# 判断经纪人级别是否为A3
df['经纪人级别'].isin(['A3'])
# 先判断结果,将结果为True的提取
#先判断经纪人级别列里是否包含A3和M4,然后将复合条件的数据提取出来。
df.loc[df['经纪人级别'].isin(['A3','M4'])]
# 使用&(并)与| (或)操作符或者特定的函数实现多条件筛选
# A列值大于10, 并且B列值大于5
df[(df['A'] > 10) & (df['B'] >5)]
df[np.logical_and(df['A'] > 10, df['B'] > 5)]
# A列值大于10,或 B列值大于5
df[(df['A'] > 10) | (df['C'] >20)]
df[np.logical_or(df['A'] > 10, df['C'] > 20)]
- 按索引进行提取
# 按标签索引
df[1:4]
# 传入列名
df[['A', 'B']]
# loc函数
# 知道column names 和index(这里df的index没有指定,是默认生成的下标),且两者都很好输入,可以选择 .loc同时进行行列选择
# 根据标签取第一行, 显示为DataFrame格式
df.loc[:0]
# 取标签为2,3,4, A列的数据, 显示为Series格式
df.loc[2:4, 'A']
# iloc函数
# 行和列都用index来进行提取
df.iloc[0:5, 1:3]
# 返回第一行
df.iloc[0,:]
# 返回第一列的第一个元素
df.iloc[0,0]
#[0, 2, 5] 代表指定的行,[ 4, 5 ] 代表指定的列
df.iloc[[0,2,5],[4,5]]
# ix
#ix的功能更加强大,参数既可以是索引,也可以是名称,相当于,loc和iloc的合体
df.ix[1:3, ['A', 'B']]
# at函数
根据指定行index及列label,快速定位DataFrame的元素,选择列时仅支持列名
df.at[3, 'A']
# iat函数
选择时只使用索引参数
df.iat[3, 2]
- 按日期进行提取
import pandas
import datetime as dt
# 重新设置索引
df.reset_index()
#设置日期为索引
df=df.set_index('日期')
#提取2016年11月2号的数据
df['2016-11-02' : '2016-11-02']
dt_time = dt.datetime(year = 2018, month=9, day = 17, hour = 22, minute = 43)
print(dt_time)
#构造时间
ts = pd.Timestamp('2018-09-17 22:43:00')
ts = pd.to_datetime('2018-09-17 22:43:00')
ts = pd.to_datetime('17/09/2018 22:43:00')
# 月份
ts.month
#日期
ts.day
# 加日期
ts + pd.Timedelta(' 10 days')
ts.hour
# 构造时间序列, 构造十个日期, 每12分钟一次
pd.Series(pd.date_range(start = '2018-09-17 22:43:00', periods = 10, freq = '12min'))
读取文件, 有时间列, 先将时间字符串转换成时间格式, 再进行处理
或当读取数据时, 就对数据格式进行修改
data = pd.read_csv('.../db.csv', index_col = 0, parse_dates = True)
# 读取时间为2013年的所有数据
data['2013']
# 取所有8点到12点之间的数据, 不包含8点和12点
data[(data.index.hour > 8) & (data.index.hour < 12)]
# 包含8点到12点
data.between_time('08:00', '12:00')
# 时间序列的重采样-看每月的平均值
data.resample('M').mean()
数据汇总
- 对数据进行分类 - group by函数
# 创建数组
df = pd.DataFrame({'key' : ['a', 'b', 'c','a', 'b', 'c','a', 'b', 'c'],
'data' : [0, 2, 4, 5, 6, 7, 8, 9, 4]})
# 分别计算a, b, c 的和
df.groupby('key')['data'].sum()
df.groupby('key')['data'].mean()
s = pd.Series([1, 2, 3,1, 2, 3],[8,7,6,8,7,6])
# 对索引进行排序
grouped = s.groupby(level = 0, sort =False)
grouped.first()
df2 = pd.DataFrame({'x':['a', 'b', 'a', 'b'],
'y' : [1, 2, 3, 4]})
# 只关注x中的b
df3 = df2.groupby(['x']).get_group('b')
# 查看个数
df2.size()
2, 对数据进行透视
pd.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean')
df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
"bar", "bar", "bar", "bar"],
"B": ["one", "one", "one", "two", "two",
"one", "one", "two", "two"],
"C": ["small", "large", "large", "small",
"small", "large", "small", "small",
"large"],
"D": [1, 2, 2, 3, 3, 4, 5, 6, 7]})
table = pd.pivot_table(df, values='D', index=['A', 'B'],
columns=['C'], aggfunc=np.sum)
- 对数据进行映射
# 用map函数对字典进行映射, 新加一列
data['upper'] = data['group'].map(dataUpper)
数据统计
- 数据采样
# 简单随机抽取sample
df.sample(n=3)
# 设置采样权重
# 需要对每一行进行权重设置,列表行数少可行,过多不可行
# 假设有4行数据,设置采样权重
weights = [0, 0, 0.5, 0.5]
df.sample(n=4, weights=weights)
## 确定采样后是否放回
# 采样后放回,True
df.sample(n=6, replace=True)
- 统计计算
# 描述统计 describe函数
#自动生成数据的数量,均值,标准差等数据
#round(2),显示小数点后面2位数,T转置
df.describe().round(2).T
# 标准差std()
df['经纪人响应时长'].std()
# 协方差cov
df['经纪人当天发送消息数'].cov(df['客户当天发送消息数']
# 相关性分析corr
df['客户当天发送消息数'].corr(df['经纪人当天发送消息数'])
# 中位数
df.median()
对字符串进行操作
- 大小写
a.lower()
a.upper()
- 长度
# 长度
a.len()
- 去除空格
a.strip()
a.lstrip()
alrstrip()
- 替换
df.columns.str.replace(' ', '_')
- 切分与分列
#切分
a.split('_')
# 切分, 且成为新列
a.split('_', expand = True)
# 对切分进行限制, 只切1次
a.split('_', expand = True, n=1)
# 查看是否包含
a.str.contains('A')
# 分列
s.str.get_dummies(sep= '|')