pandas数据处理
本文用到的数据和源代码
链接:https://pan.baidu.com/s/17uA0t50vXDOe-aPigtZZ9Q
提取码:97xz
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
1、删除重复元素
使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
data = pd.read_excel('销售记录.xlsx')
data = data.append(data.iloc[:1111],ignore_index=True)
#获取最后一行最后一列
data.iloc[-1,-1] = 100
data.shape
df.duplicated() 返回bool型的值,如果不重复返回false ,有重复值返回Ture
#这里是没有重复的数据
cond = data.duplicated()
inds = data.loc[cond].index
data.drop(labels=inds).shape
2. 映射
映射的含义:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定
需要使用字典:
`map = {
'label1':'value1',
'label2':'value2',
...
}
`
包含三种操作:
- replace()函数:替换元素
- 最重要:map()函数:新建一列,修改一列
- rename()函数:替换行索引
使用replace()函数,对values进行替换操作
1)replace还经常用来替换NaN元素
data.iloc[100,-1] = np.nan
data.iloc[1001,-1] = np.nan
data.iloc[1024,-1] = '?'
data.isnull().sum()
#填补空缺
data.fillna(value=0,inplace=True)
#已知道哪些值我们不需要
#to_replace:需要执行一套什么样的替换规则,数据类型要使用dict
to_replace = {
'?':0,'??':0,np.nan:0}
data.replace(to_replace,inplace=True)
data.iloc[1024]
2) rename()函数:替换索引
demo = data.head(n=10)
demo.index = ['东邪','西毒','南帝','北丐','中神通']+['东邪','西毒','南帝','北丐','中神通']
mapper = {
'东邪':'东西','西毒':'蛤蟆'}
demo.rename(mapper)
3) map()函数:新建一列
使用map()函数,由已有的列生成一个新列
适合处理某一单独的列,支持Series类型
注意:map函数的参数支持function和dict
function在定义的时候,必须要写一个形参,形参会代表一列中每一个元素(map函数会自动遍历)
#映射修改
demo = data.copy()
#把下单的日期只提取月份
def get_m(item):
return str(item).split()[0].split('-')[1]
#demo是一个dataframe
demo.loc[:,'下单日期'] = demo.loc[:,'下单日期'].map(get_m)
#映射类型替换
#昨天绘制散布图出现了一个问题,鸢尾花数据的类别值是str类型,散布图不支持
#.astype('category').cat.codes
import seaborn as sns
iris = sns.load_dataset('iris')
#['setosa', 'versicolor', 'virginica'] => [0,1,2]
iris.species.unique()
#1.字典替换方式 {
'setosa':0, 'versicolor':1, 'virginica':2} 比较固定
#加入类别的数量是动态的
#2.使用函数自动识别
#设置全局变量,获取当前的类别数量
cls = iris.species.unique()
def str2num(item):
for i in np.arange(cls.shape[0]):
if item == cls[i]:
return i
iris['lables']=iris.species.map(str2num)
iris
plt.scatter(x = iris.iloc[:,0],y=iris.iloc[:,1],c=iris.iloc[:,-1])
transform()和map()类似
transform是变形的意思
transform中的值只能是一个function
#transform不支持字典映射
to_place={
'setosa':0, 'versicolor':1, 'virginica':2}
iris.species.transform(to_place)
iris.species.transform(str2num)
apply()
iris.species.transform(to_place)
iris.species.apply(str2num)
agg()
iris.species.agg(to_place)
iris.species.agg(str2num)
3. 异常值检测
使用describe()函数查看每一列的描述性统计量
iris.iloc[:,:-1].describe()
sns.boxplot(data=iris.iloc[:,:-1])
使用std()函数可以求得DataFrame对象每一列的标准差
根据每一列的标准差,对DataFrame元素进行过滤。
借助any()函数, 测试是否有True,有一个或以上返回True,反之返回False
对每一列应用筛选条件,去除标准差太大的数据
4. 排序
sort_values() sort_index()
#根据行索引排序
data.sort_index(ascending=False)
#order by 列
data.sort_values(by=['销售代表ID','数量']).iloc[:10]
5. 数据聚合【重点】
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
数据分类处理:
- 分组:先把数据分为几组
- 用函数处理:为不同组的数据应用不同的函数以转换数据
- 合并:把不同组得到的结果合并起来
数据分类处理的核心:
groupby()函数
groupby()在pandas中也担任分组的重担
如果想使用color列索引,计算price1的均值,可以先获取到price1列,然后再调用groupby函数,用参数指定color这一列
使用.groups属性查看各行的分组情况:
pd.DataFrame(data.groupby(by='客户省份').金额.sum())
# select avg(age) from table_name where group by age,sex;
#分组的意义在与更好的统计
for i in data.iloc[:100].groupby(by='客户省份'):
display(i[1])
data.groupby(by='客户省份').__dict__
add_prefix()添加前缀
pd.DataFrame(data.groupby(by='客户省份').金额.sum()).add_prefix('总')
可以使用pd.merge()函数将聚合操作的计算结果添加到df的每一行
使用groupby分组后调用加和等函数进行运算,让后最后可以调用add_prefix(),来修改列名
可以使用transform和apply实现相同功能
在transform或者apply中传入函数即可
data.groupby(by=[‘客户省份’]).金额.agg(sum).sort_values()
### transform()与apply()函数还能传入一个函数或者lambda
`
df = DataFrame({
'color':['white','black','white','white','black','black'],
'status':['up','up','down','down','down','up'],
'value1':[12.33,14.55,22.34,27.84,23.40,18.33],
'value2':[11.23,31.80,29.99,31.18,18.25,22.44]})
apply的操作对象,也就是传给lambda的参数是整列的数组
离散化和分箱
- 字符型和范围型
- 方便观察和统计
- pd.cut(),映射成一个范围类型
import warnings
warnings.filterwarnings('ignore')
#奥巴马 和 罗姆尼
ele = pd.read_csv('usa_election.csv')
ele.info()
#美国选举制度 全民选举 民主
#人民支持谁 就会给谁投票 募捐
#候选人的名称
ele.cand_nm.unique()
奥巴马VS罗姆尼
#数据的过滤 ,保留奥巴马和罗姆尼的数据
bin_ = ele.query("cand_nm=='Obama, Barack' | cand_nm=='Romney, Mitt'")
#Google 红衫资本 微软 沃尔玛 高盛
#某个范围数的金额 0-1 1-10 10-100 100-1000 1000-10000 10000-100000 10000.....
#要求分类的策略需要制定好,需要的是序列类型
bins = [0,1,10,100,1000,10000,100000,1000000,10000000,1000000000]
#把金额范围的分类数据 添加为新的一列
bin_['amt_range'] = pd.cut(bin_.contb_receipt_amt,bins)
bin_.head()
#被分箱以后的金额数据一共有9类
bin_['amt_range'].unique().size
#观察分情况
vs = bin_.groupby(by=['amt_range','cand_nm']).contb_receipt_amt.count().unstack()
vs
vs.plot(kind='barh')
#堆叠图 比例图形
total = vs.sum(axis=1)
total
#计算每个投票占用的比例
res = vs.divide(total,axis=0)
#面积图
res.plot(kind='barh',stacked=True)
plt.legend(loc=[0,1])
时间序列
- 时间类型是连续型
- 时间可以当作行索引
#把字符串的时间转变为时间类型
bin_.contb_receipt_dt = pd.to_datetime(bin_.contb_receipt_dt)
bin_.head()
重采样
降采样 : 把高频的数据转换为低频的数据
- 数据量大,计算效率下降
- 数据不容易观察
- 要求行索引必须是时间序列
- .resample()
bin_.sort_index()
#bin_.set_index('contb_receipt_dt',inplace=True)
#rule : Y年 M月 D日
#每个月,用于政治献金的钱是多少
bin_.resample('M').contb_receipt_amt.sum()
#每个月 奥巴马和罗姆尼分别接受的政治献金
A = bin_.groupby('cand_nm').resample('M').contb_receipt_amt.sum().unstack().T
A
A.plot(kind='bar')
#每个月 奥巴马和罗姆尼分别获取的投票数
B = bin_.groupby('cand_nm').resample('M').contb_receipt_amt.count().unstack().T
B
B.plot(kind='area',alpha=0.6,figsize=(15,5))
#获取美国各个州都是支持谁的
res = bin_.groupby(['cand_nm','contbr_st']).contb_receipt_amt.count().unstack().T.dropna()
res.plot(kind='area',figsize=(15,5))
#使用堆叠图 比例
stacked_img_data = res.divide(res.sum(axis=1),axis=0)
stacked_img_data.plot(kind='barh',stacked=True,figsize=(8,12))
plt.legend(loc=[0,1])
大数据读取
假如一个数据文件它的大小是40GB,现在想得每个时刻每台服务器的并发量
data.shape
import pandas as pd
#分片读取 skip() limit()
#skiprows=None (跳过多少行), nrows=None (获取多少行)
#查找最大值,每次读取100行
#把其它的最大金额给存储起来
max_data = []
#代表循环的次数
n = 0
while True:
if n == 0:
df = pd.read_excel('销售记录.xlsx',skiprows=n,nrows=100,header=None).iloc[1:]
max_data.append(df.iloc[:,-1].max())
else:
df = pd.read_excel('销售记录.xlsx',skiprows=n*100,nrows=100,header=None)
#dataframe中获取的数据大于1行
if df.shape[0] > 0:
max_data.append(df.iloc[:,-1].max())
else:
break
n += 1
np.max(max_data)
电脑配置不太好的话不要轻易尝试哦会卡哈哈~