使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
# color 0 :red;1:green;2:blue
df = DataFrame({'color':np.random.randint(0,3,size = 300),'num':np.random.randint(0,5,size = 300)})
df
#或者:
b=np.random.choice(['B','M'],size=(100,2))
b1=DataFrame(b,columns=['True','Predict'])
b1
# 计算True的总个数,即计算重复的总行数
df.duplicated().sum()
Out: 285
df.drop_duplicates()
img = plt.imread('./芝麻.jpg')
img.shape
Out: (662, 1000, 3)
# 这张图片总共有多少个像素呢?
# (红,绿,蓝)
662*1000
Out: 662000
# numpy没有去重的方法
img2 = img.reshape(-1,3)
img2
# img2 必须是转化成n行n列,比如reshape(-1,3)
df = DataFrame(img2,columns=['red','green','blue'])
df
# 总数据662000
# 非重复的像素,71526个 ,inplace=True则能修改原数组
df.drop_duplicates().shape
Out: (71526, 3)
【注意】如果使用pd.concat([df1,df2],axis = 1)生成新的DataFrame,新的df中columns相同,使用duplicate()和drop_duplicates()都会出问题
映射的含义:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定
需要使用字典:
map = { 'label1':'value1', 'label2':'value2', ... }
包含三种操作:
使用replace()函数,对values进行替换操作
df = DataFrame({'color':np.random.randint(0,3,size = 300),'num':np.random.randint(10,30,size = 300)})
df
m = {0:'red',1:'green',2:'blue'}
# replace方法,可将DataFrame中所有满足条件的数据,进行替换
df.replace(m)
# 字典的key类型要一致
m = {0:'red',1:'green',2:'blue',1024:'purple',2048:'cyan'}
# 字典中映射关系,键值对,去DataFrame找数据,找到了就替换,没有找到,也不会报错
df.replace(m)
数据集 data1 ——> 杂质:-数字\t
法①:遍历—> re.sub
import re
data1[0].map(lambda x: re.sub('.*\d+\\t','',x))
法②【一定要加上.str才能替换】:data1[0].str.replace
pd.DataFrame(data1[0].str.replace('.*?\d+?\\t ', '')) #用正则表达式修改数据
使用map()函数,由已有的列生成一个新列
适合处理某一单独的列。
仍然是新建一个字典
map()函数中可以使用lambda函数
transform()和map()类似
使用map()函数新建一个新列
df = DataFrame(np.random.randint(0,150,size = (10,3)),
columns=['Python','Math','En'],index=list('ABCDEFGHJK'))
df
# df['Python'] 10 个数据 迭代器
df['Java'] = df['Python'].map(lambda x : 2*x - 100)
df
f = lambda x : x*2 - 100
type(f)
Out: function
def fun(x):
x*2 - 100
type(fun)
Out: function
def convert(x):
if x >=130:
return '优秀'
elif x <130 and x >=100:
return '良好'
elif x < 100 and x >=80:
return '中等'
elif x < 80 and x >=60:
return '及格'
else:
return '不及格'
df['Level'] = df['Python'].map(convert)
df
# Python 这一列,老师出考题的时候,有一道题出错了,每个人Python加10分
df['Python'] += 10
df
# map 这个方法,可以修改当前的列
df['Python'] = df['Python'].map(lambda x :x + 10)
df
分箱、分块、分类——》
# 分箱,分类
# 葡萄品质0~10
# 0~4 low
# 5~7 median
# 8~10 high
# 分箱,分类
# 葡萄品质0~10
# 0~4 low
# 5~7 median
# 8~10 high
# 0 ~ 10 信用
# 0~3 low
# 4~ 6 median
# 7~10 high
# 根据这个人手机产生数据
def convert(x):
if x >=140:
return 150
elif x < 140 and x >= 100:
return 125
elif x < 100 and x>=60:
return 80
else:
return 0
df['Python'] = df['Python'].map(convert)
df
df = DataFrame(np.random.randint(0,150,size = (4,3)))
df
# 更改列标题 【axis = 0 行】
m = {0:'张三',1:'李四',2:'王五',3:'小刘'}
df.rename(m,axis = 0,inplace=True)
# 更改行标题
m = {0:'Python',1:'Math',2:'En'}
df.rename(m,axis = 1,inplace=True)
df
使用describe()函数查看每一列的描述性统计量
df = DataFrame(np.random.randn(10000,3),columns=list('ABC'))
df
# 过滤条件,大于5倍平均,异常
# 均值0.79,则大于3.95为异常值
df.abs().mean()
Out:
A 0.798357
B 0.793909
C 0.789348
dtype: float64
# 找出各个属性的异常值
cond = df.abs() > 3.95
cond.sum()
Out:
A 2
B 2
C 0
dtype: int64
# 异常值总和
(cond.sum()).sum()
# 异常值总行数
cond.any(axis = 1).sum()
Out: 4
# 以DataFrame形式展示存在异常值的行数
df[cond.any(axis = 1)]
展示满足要求的数据:
# 满足要求的数据
cond = df.abs() <=3.95
cond = cond.all(axis = 1)
df[cond]
3原则:如果数据服从正态分布,在3原则下,异常值被定义为一组测定值中与平均值的偏差超过3倍标准差的值。在正态分布的假设下,距离平均值3之外的值出现的概率为P(|x-|>3)≤0.003,属于极个别的小概率事件。
#平均值上下三倍标准差之间属于正常点
std=df.abs().std()
std
Out:
A 0.607076
B 0.598781
C 0.594652
dtype: float64
mean=df.abs().mean()
mean
Out:
A 0.798357
B 0.793909
C 0.789348
dtype: float64
low=mean-3*std
high=mean+3*std
display(low.mean(),high.mean())
Out:
-1.0066372280404017
2.5943795581659246
# 异常值 位于小于mean-3*std or 大于mean+3*std
low1=df.abs() high.mean()
low_high1=np.logical_or(low1,high1)
low_high1
# 显示异常值个数
df[low_high1.any(axis=1)].shape
Out: (259, 3)
# 过滤掉正常值,显示异常值
df[low_high1.any(axis=1)]
#平均值上下三倍标准差之间属于正常点
lowcond=df.abs()>low.mean()
highcond=df.abs() < high.mean()
low_high=np.logical_and(lowcond,highcond)
low_high
# 过滤异常值,满足条件 df.mean()-3*df.std() ~ df.mean()+3*df.std()
df[low_high.all(axis=1)].shape
Out: (9741, 3)
df.shape
Out:(10000, 3)
259+9741=10000
df =DataFrame(
{'height':np.random.randint(150,200,1000),
'weight':np.random.randint(50,90,size = 1000)})
df
# 创造异常值
# 每隔10个数据加一个300,比如第10个原本63,处理后变363,第20,30..一样
df['weight'][::10] +300
df
# 判定异常值范围:
# 体重的异常值:>300公斤
cond = df['weight'] < 300
# 异常值筛选:给定条件(数据不同,条件不一样,根据数据属性来做选择)
df[cond]
使用.take()函数排序,可以借助np.random.permutation()函数随机排序
df.take([100,300,210])
# 产生5个0-4的随机数
np.random.permutation(5)
Out: array([2, 0, 4, 3, 1])
# 产生1000个0-999的随机数
index = np.random.permutation(1000)
index
type(index)
Out: numpy.ndarray
# 使用产生的随机数作为下标排序显示数据
df.take(index)
# 产生1000个从0~999的升序数列
index = np.arange(1000)
index
# 打乱0~999的顺序数列
np.random.shuffle(index)
index
display(type(index),index)
Out: numpy.ndarray
# 使用随机打乱的数列作为下标显示数据
df.take(index)
当DataFrame规模足够大时,直接使用np.random.randint()函数,就配合take()函数实现随机抽样
df = DataFrame(np.random.randn(10000,3),columns=list('ABC'))
df
df.size
Out: 30000
ss=np.random.randint(0,10000,size = 100)
ss
Out:
array([4065, 9998, 4088, 2039, 4184, 1807, 1325, 1569, 6657, 2974, 3211,
2982, 8154, 7668, 6738, 7486, 4362, 105, 6373, 3119, 1261, 1648,
2962, 7112, 2243, 6014, 2211, 6357, 2032, 1761, 7664, 6734, 1882,
6126, 8942, 4872, 8935, 9207, 4533, 4558, 9922, 5127, 9340, 5148,
640, 8374, 5681, 1160, 325, 2469, 9823, 7114, 8228, 5019, 4217,
2901, 8420, 4888, 4274, 6595, 2289, 1446, 8035, 958, 736, 7005,
5490, 2752, 3260, 9686, 5241, 3165, 8381, 7885, 4582, 8015, 7215,
8430, 8921, 4957, 2419, 7912, 9510, 1614, 1102, 3070, 2390, 228,
3588, 829, 6808, 4883, 349, 1869, 2073, 1992, 9280, 1085, 5495,
5396])
DataFrame(ss)[0].unique().size
Out: 100
# 可以直接使用random.randint 产生的数据来做下标随机抽取数据
df.take(np.random.randint(0,10000,size = 100))