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)

电脑配置不太好的话不要轻易尝试哦会卡哈哈~