Pandas数据处理

一:删除重复元素

使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True

    - keep参数:指定保留哪一重复的行数据

    
import numpy as np
from pandas import DataFrame,Series
import pandas as pd


#创建具有重复元素行的DataFrame

#创建一个df
df = DataFrame(data=np.random.randint(0,100,size=(9,5)))
df.iloc[1] = [6,6,6,6,6]
df.iloc[3] = [6,6,6,6,6]
df.iloc[5] = [6,6,6,6,6]
df

	0	1	2	3	4
0	95	45	44	19	97
1	6	6	6	6	6
2	80	31	49	27	7
3	6	6	6	6	6
4	70	5	58	20	48
5	6	6	6	6	6
6	88	47	31	63	39
7	8	52	96	8	51
8	14	83	42	3	33

使用drop_duplicates()函数删除重复的行
	- drop_duplicates(keep='first/last'/False)

df.drop_duplicates(keep='first')
	0	1	2	3	4
0	95	45	44	19	97
1	6	6	6	6	6
2	80	31	49	27	7
4	70	5	58	20	48
6	88	47	31	63	39
7	8	52	96	8	51
8	14	83	42	3	33

二:映射

1) replace()函数:替换元素

DataFrame替换操作
	单值替换
        普通替换: 替换所有符合要求的元素:to_replace=15,value='e'
        按列指定单值替换: to_replace={列标签:替换值} value='value'

	多值替换
        列表替换: to_replace=[] value=[]
        字典替换(推荐) to_replace={to_replace:value,to_replace:value}

        
# 1       
df.replace(to_replace=6,value='six')

	0	1	2	3	4
0	95	45	44	19	97
1	six	six	six	six	six
2	80	31	49	27	7
3	six	six	six	six	six
4	70	5	58	20	48
5	six	six	six	six	six
6	88	47	31	63	39
7	8	52	96	8	51
8	14	83	42	3	33

# 2
df.replace(to_replace={3:'three'})

	0	1	2	3	4
0	95	45	44	19	97
1	6	6	6	6	6
2	80	31	49	27	7
3	6	6	6	6	6
4	70	5	58	20	48
5	6	6	6	6	6
6	88	47	31	63	39
7	8	52	96	8	51
8	14	83	42	three	33


# 3
df.replace(to_replace={3:6},value='six')


	0	1	2	3	4
0	95	45	44	19	97
1	6	6	6	six	6
2	80	31	49	27	7
3	6	6	6	six	6
4	70	5	58	20	48
5	6	6	6	six	6
6	88	47	31	63	39
7	8	52	96	8	51
8	14	83	42	3	33
2) map()函数:新建一列 ,   map函数并不是df的方法,而是series的方法

map()可以映射新一列数据
map()中可以使用lambd表达式
map()中可以使用方法,可以是自定义的方法

eg:map({to_replace:value})

注意 map()中不能使用sum之类的函数,for循环



# - 新增一列:给df中,添加一列,该列的值为中文名对应的英文名

dic = {
    'name':['jay','tom','jay'],
    'salary':[9999,5000,9999]
}
df = DataFrame(data=dic)
df
	name	salary
0	jay		9999
1	tom		5000
2	jay		9999




dic = {
    'jay':'周杰伦',
    'tom':'张三'
}
df['c_name'] = df['name'].map(dic)
df

	name	salary	c_name
0	jay		9999	周杰伦
1	tom		5000	张三
2	jay		9999	周杰伦



# map当做一种运算工具,至于执行何种运算,是由map函数的参数决定的(参数:lambda,函数)¶
	# 使用自定义函数
    
def after_sal(s):
    return s - (s-5000)*0.5

#超过3000部分的钱缴纳50%的税
df['after_sal'] = df['salary'].map(after_sal)
df

	name	salary	c_name	after_sal
0	jay		9999	周杰伦	  7499.5
1	tom		5000	张三	   5000.0
2	jay		9999	周杰伦	  7499.5


df['salary'].apply(after_sal)
0    7499.5
1    5000.0
2    7499.5
Name: salary, dtype: float64
        
        
### 注意:并不是任何形式的函数都可以作为map的参数。只有当一个函数具有一个参数且有返回值,那么该函数才可以作为map的参数。

三:使用聚合操作对数据异常值检测和过滤

使用df.std()函数可以求得DataFrame对象每一列的标准差
	- 创建一个1000行3列的df 范围(0-1),求其每一列的标准差


df = DataFrame(data=np.random.random(size=(1000,3)),columns=['A','B','C'])
df.head()

	A			B			C
0	0.421703	0.113982	0.378142
1	0.135788	0.202773	0.556716
2	0.026390	0.869824	0.780703
3	0.267029	0.302224	0.544516
4	0.404328	0.367307	0.035302


# 对df应用筛选条件,去除标准差太大的数据:假设过滤条件为 C列数据大于两倍的C列标准差
std_twice = df['C'].std() * 2
std_twice	# 0.5809347094044642

df['C'] > std_twice
#异常值对应的行数据
df.loc[df['C'] > std_twice]
indexs = df.loc[df['C'] > std_twice].index
df.drop(labels=indexs,axis=0,inplace=True)




- 数据清洗
    - 清洗空值
        - dropna  fillna  isnull notnull  any  all
    - 清洗重复值
        - drop_duplicates(keep)
    - 清洗异常值
        - 异常值监测的结果(布尔值),作为清洗的过滤的条件

四:排序

使用.take()函数排序
    - take()函数接受一个索引列表,用数字表示,使得df根据列表中索引的顺序进行排序
    - eg:df.take([1,3,4,2,5])
        
可以借助np.random.permutation()函数随机排序

df.take([2,1,0],axis=1).take(np.random.permutation(500),axis=0)

#随机取20行
df.take([2,1,0],axis=1).take(np.random.permutation(500),axis=0)[0:20]


- np.random.permutation(x)可以生成x个从0-(x-1)的随机数列


# 随机抽样
当DataFrame规模足够大时,直接使用np.random.permutation(x)函数,就配合take()函数实现随机抽样

五:数据分类处理 [重点]

数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。

数据分类处理:

     - 分组:先把数据分为几组
     - 用函数处理:为不同组的数据应用不同的函数以转换数据
     - 合并:把不同组得到的结果合并起来
 
数据分类处理的核心:
     - groupby()函数
     - groups属性查看分组情况
     - eg: df.groupby(by='item').groups
# 分组
from pandas import DataFrame,Series

df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],
                'price':[4,3,3,2.5,4,2],
               'color':['red','yellow','yellow','green','green','green'],
               'weight':[12,20,50,30,20,44]})
df

	item	price	color	weight
0	Apple	4.0		red		12
1	Banana	3.0		yellow	20
2	Orange	3.0		yellow	50
3	Banana	2.5		green	30
4	Orange	4.0		green	20
5	Apple	2.0		green	44


# - 使用groupby实现分组
df.groupby(by='item')
# <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000023E4349CCC0>


# - 使用groups查看分组情况
# 该函数可以进行数据的分组,但是不显示分组情况
df.groupby(by='item').groups

{'Apple': Int64Index([0, 5], dtype='int64'),
 'Banana': Int64Index([1, 3], dtype='int64'),
 'Orange': Int64Index([2, 4], dtype='int64')}

# 给df创建一个新列,内容为各个水果的平均价格
# 1  这是错误的  这个方法不太好
df.groupby(by='item').mean()['price']

item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64

 
# 2  这是正确的 把 .mean() 放后面,先找到后计算
mean_price_s = df.groupby(by='item')['price'].mean()
mean_price_s

item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64

# 3  
dic = mean_price_s.to_dict()
dic
# {'Apple': 3.0, 'Banana': 2.75, 'Orange': 3.5}


# 4
df['mean_price'] = df['item'].map(dic)
df
	item	price	color	weight	mean_price
0	Apple	4.0		red		 12		3.00
1	Banana	3.0		yellow	 20		2.75
2	Orange	3.0		yellow	 50		3.50
3	Banana	2.5		green	 30		2.75
4	Orange	4.0		green	 20		3.50
5	Apple	2.0		green	 44		3.00

六:高级数据聚合

使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算

     - df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
     - transform和apply都会进行运算,在transform或者apply中传入函数即可
     - transform和apply也可以传入一个lambda表达式


def my_mean(s):
    sum = 0
    for i in s:
        sum += i
    return sum/s.size

df.groupby(by='item')['price'].transform(my_mean)

0    3.00
1    2.75
2    3.50
3    2.75
4    3.50
5    3.00
Name: price, dtype: float64


        
df.groupby(by='item')['price'].apply(my_mean)
item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64
posted @ 2019-08-14 21:53  量子世界  阅读(135)  评论(0)    收藏  举报