data.info
:查看数据的基本结构组成和对应的属性
data.shape
:查看数据的行数和列数
data.head(n)
:显示数据的前n行
data.columns
:显示所有的列名
data.columns
= [“A”“C”“W"d"d"e”] :按顺序设置新的列名
更改列名
data.rename(columns={'id':'ID', '原来的列名':'新的列名'})
data[column].value_counts()
:显示每一列对应的分类,每一类的个数/比例
'''
获取columnName对应列的各个分类的数量和比例
'''
def getColumnNumsAndRatio(columnName, data, dropNan=True, sort=True, normalize=True):
# 获取某一列的各类别的个数
cat_nums = data[columnName].value_counts()
# 获取某一列各类别的占比
cat_ratio = data[columnName].value_counts(normalize = normalize)
# 组合个数、占比
numAndRatio = pd.concat([cat_nums, cat_ratio],axis=1)
# 更改列名
numAndRatio.columns = [columnName+'各分类数量', columnName+'各分类占比']
return numAndRatio
'''
获取数据中每个特征缺失的情况
'''
def getNullInfoAboutColumns(data):
missNumber = data.isnull().sum().sort_values(ascending = False)
missPercent = (missNumber / data.shape[0]).sort_values(ascending = False)
nullNumberAndPrecent = pd.concat([missNumber, missPercent], axis =1, keys = ['缺失数量','缺失占比'])
return nullNumberAndPrecent
# 统计重复的样本个数
data.duplicated().sum()
# 删除重复的样本
data.drop_duplicates(inplace = True)
# 所有数据的分布情况
data.describe()
# 对应column列的分布情况
data[column].describe()
绘制概率密度图
import seaborn as sns
plt.figure(figsize=(10, 8), dpi=80)
#绘图
sns.kdeplot(data["订单金额"], # 对应的列
shade=True,
color="#01a2d9", # 颜色
label="订单金额",
alpha=.7)
#风格与装饰
sns.set(style="whitegrid", font_scale=1.1)
plt.title("订单金额概率密度分布图",fontsize=18)
plt.yticks([])
plt.xlim((-1,40000))
plt.show()
获取对应列异常值的索引
'''
columns: list列表
'''
def getFeatureAbnormalIndex(data, columns):
numOfSample = data.shape[0]
listAbnormalIdx = []
for idx, column in enumerate(columns):
feature = data[column]
# 获取25%的数据值
QL = feature.quantile(0.25)
# 获取75%的数据值
QU = feature.quantile(0.75)
IQR = QU - QL
# 异常值的定义方式
abnormal = feature[((feature < (QL - 1.5 * IQR)).astype(int) + (feature > (QU + 1.5*IQR)).astype(int)) !=0]
listAbnormalIdx.extend(abnormal.index)
# 去重
listAbnormalIdx = list(set(listAbnormalIdx))
return listAbnormalIdx
创建新的数据并计算和之前列的相关系数
'''
column:列名
newColumn:增加列的名称
newColumnIndex:list 对应这些的索引值需要改变
'''
def makeNewFeatureAndcomputeCorration(data, column, newColumn, newColumnIndex):
# 创建索引和需要建立相关系数的列相同的缩影
df = pd.DataFrame(index = data.index)
# 设置初始值
df[newColumn] = 0
# 设置需要改变的值
df.loc[newColumnIndex, newColumn] = 1
# 计算相关系数
corration = pd.concat([df[newColumn], data[column]], axis=1).corr()
return corration
loc提取:按标签提取
iloc提取:按照位置进行提取
data[]提取:
data[]可以输入的值:
只能是单独对应列的名称,取一列
df = pd.DataFrame([(.2, .3, 2.5), (.0, .6, 3.6), (.6, .0, .3), (.2, .1, .2)],columns=['dogs', 'cats', 'pig'], index=list("ABCD"))
# 只能单独索引列
df['dogs']
df['pig']
pandas.DataFrame.loc() 允许输入的值:
df = pd.DataFrame([(.2, .3, 2.5), (.0, .6, 3.6), (.6, .0, .3), (.2, .1, .2)],columns=['dogs', 'cats', 'pig'], index=list("ABCD"))
# 索引行
# 单一索引行
df.loc['A']
# 搜索若干行,对应行的列表即可
df.loc[["A", "B"]]
# 索引列
# 单一索引一列列
df.loc[:,'dogs']
# 搜索若干行,对应行的列表即可
df.loc[:,["dogs", "pigs"]]
# 索引某行某列
# 确定的值
df.loc['A', "dogs"]
# 搜索若干行,若干列
df.loc[["A", "B"],['dogs', 'pig']]
df.loc[["A", "B"],:]
pandas.DataFrame.iloc()允许输入的值:
整数5、整数列表或数组[4,3,0]、整数的切片对象1:7
df = pd.DataFrame([(.2, .3, 2.5), (.0, .6, 3.6), (.6, .0, .3), (.2, .1, .2)],columns=['dogs', 'cats', 'pig'], index=list("ABCD"))
#对应的索引坐标或者切片,列表
df.iloc[x,y]
df.iloc[2]
df.iloc[2:,1:]
df.iloc[1,2]
df.iloc[[1,3],[1,2]]
选取满足的值进行选取
1、将满足origin是China且money小于35这两个条件的数据,返回其id、date、money、product、department、origin值。
data.loc[(data['origin']=="China") & (data['money']<35),['id','date','money','product','department','origin']]
2、将满足origin是China或者money小于35这两个条件之中任意一个条件的数据,返回其id、date、money、product、department、origin值。
data.loc[(data['origin']=="China") | (data['money']<35),['id','date','money','product','department','origin']]
值的判断
方式一:判断origin列的值是否为China
data['origin']=="China"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w48usB9L-1642064510741)(C:\Users\zjy\Desktop\xiangmu\数据分析项目\国美异常检测\图片\image-20220113002738368.png)]
方式二:判断department列的值是否为水果
data['department'].isin(['水果'])
提取符合判断的值
data.loc[data['origin'].isin(['Thailand'])] # 将产地是泰国的数据进行提取
选取一个特征进行去重
'''
选取一列进行去重
column: str
'''
def getUniqueByColumn(data, column):
uniqueColumn = data[column].unique()
return uniqueColumn
按比例划分数据集train、test
'''
划分数据集
column: str 按照数据的某一列划分
uniqueColumn: 某一列的数据
sampleRatio: 抽样比例
'''
def makeTrainAndTestData(data, column, uniqueColumn, sampleRatio=0.3):
# 按抽样比例随机选取某一指定列作为测试集一列
testDataOneColumn = random.sample(uniqueColumn.tolist(), int(len(uniqueColumn)*sampleRatio))
# 选取不包含测试样本的数据
train = data.loc[~data[column].isin(testDataOneColumn)]
# 选取包含测试样本的数据的所有测试样本
test = data.loc[data[column].isin(testDataOneColumn)]
# 更显train和test的index
train.index = range(len(train))
test.index = range(len(test))
return train, test
(1)查看某列的异常率,通常这一列中的分类适中,可以计算出每一个类中的异常率,最终使用map映射创建出新的特征列
'''
分析每一列中的特征对应的异常率
groupByColumn: 用来聚类的列
column: 一般为标签的列
'''
def getColumnAbnormalRatio(data, groupByColumn, column):
# 计算出每个类别的异常概率,如果分类标签不同方法要进行改变
abnormal = data.groupby(groupByColumn)[column].mean()
df = pd.concat([abnormal, 1-abnormal], axis = 1, keys=["异常率", "正常率"])
return df
绘制条形对比图
from pyecharts.charts import *
from pyecharts.components import Table
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
bar_hour = (
Bar(init_opts=opts.InitOpts())
.add_xaxis(ab_hour.index.to_list())
.add_yaxis("异常交易", round(ab_hour['异常率'],3).to_list(),stack = True)
.add_yaxis("正常交易", round(ab_hour['正常率'],3).to_list(),stack = True)
.set_global_opts(title_opts=opts.TitleOpts(title="【"+'下单小时'+'】'+"异常交易/全部交易的比例")
, xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)))
.set_series_opts(label_opts=opts.LabelOpts(is_show=False),xaxis_opts=opts.AxisOpts(name_rotate = 90))
)
bar_hour.render_notebook()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TVhE7cKF-1642064510743)(C:\Users\zjy\Desktop\xiangmu\数据分析项目\国美异常检测\图片\条形图)]
(2)创建新的特征
创建字典:只是用列就可以创建列和索引的字典
dict(data[column])
复杂字典:某列中类别对应的异常率
def getDict(data, groupByColumn, labelColumn):
dic = dict(data.groupby(groupByColumn)[labelColumn].mean())
return dic
'''
创建新特征
groupByColumn:分组列
labelColumn:标签列
column:老列的名称
newColumn: 新列的名称
'''
def groupByCreateFeature(train, test, groupByColumn, labelColumn, column, newColumn):
# 利用训练集数据构建字典
dic = getDict(train, groupByColumn, labelColumn)
#建立新的特征
train[newColumn] = train[column].map(dic)
test[newColumn] = test[column].map(dic)
return train, test
(3)将文字特征进行顺序编码
def easyCodeByTrainAndTest(column, train, test):
# 利用train创建字典
dic = {}
feature = np.sort(train[column].unique())
for code, cat in enumerate(feature):
dic[cat] = code
#更新train内的字段
train[column] = train[column].map(dic)
#根据test增加字典 test[column].map(dic).isnull()按照原来字典更新后为null的列的值
newCat = test.loc[test[column].map(dic).isnull(),column].unique()
for i in newCat:
dic[i] = len(dic)
#更新test字段
test[column] = test[column].map(dic)
return train, test
创建字典
# 完成了索引对应列的字典
dict(df[column])
用户ID、商品ID、品牌的特点:
①相较于之前处理的特征(商品一级类别、商品所属渠道、支付方式等)其各特征下的类别拥有交易量足够、可以衡量风险的类型;但用户ID、商品ID、品牌,这三者因为其特征下的类别较多,拥有交易过少无法判断的特点。为此,我们像先前一样新增特征“XX异常率”,但不同的是,需对未达到阈值(人为设定)的异常率特征记为-1
②用户ID、商品ID、品牌因为类别多,其特征拥有部分类别只存在于训练集,不存在与测试集的特点,为此在新增特征“XX异常率”时,这些在测试集未出现的类别对应的异常率记为-1;在特征编码时,将对这些类目手动新增
'''
获取某一分组满足特征条件的概率
比如对应品牌中,销售的数量大于10
groupByColumn 分组列
labelColumn 标签列
conditionColumn 条件列
threshold: 满足阈值的条件
'''
def columnRatioSatifyCondition(data, groupByColumn, labelColumn, conditionColumn, threshold):
columnRatio = data.groupby(groupByColumn)[labelColumn].mean()[data.groupby(groupByColumn)[conditionColumn].sum() > threshold ]
return columnRatio
'''
生成新的Data,
curColumnName: 当前处理的特征列
newColumnName: 新增特征的名称
multiplyRatio: columnRatioSatifyCondition()产生的值,满足当前列某一条件的概率进行赋值
initVal=-1: Data的初始值
'''
def getMulColumnConditionRatio(data, curColumnName, newColumnName, multiplyRatio, initVal=-1):
df = pd.DataFrame(index = data[curColumnName].unique())
df[newColumnName] = initVal
df.loc[multiplyRatio.index, newColumnName] = multiplyRatio
return df
# ratio是指满足某条件下的某一特征的异常率columnRatioSatifyCondition产生的值
def groupByFeatureMore(column, train, test, newColumn, ratio):
#创建训练集字典
# 新建数据,并指定索引
df = pd.DataFrame(index = train[column].unique())
# df新增一列设置处置为-1
df[newColumn] = -1
# 设置ratio中的值
df.loc[ratio.index, newColumn] = ratio
# 创建字典
trainDic = dict(df[newColumn])
#训练集映射
train[newColumn] = train[column].map(trainDic)
#测试集构建字典,出现在训练集的直接赋值,没有出现的设置-1
testDic = {}
for i in test[column]:
if i in ratio.index:
testDic[i] = ratio[i]
else:
testDic[i] = -1
#测试集映射
test[newColumn] = test[column].map(testDic)
return train, test
有些特征的值是连续的比如订单金额与销售数量。可以先将金额进行分箱,再利用分箱数进行统计异常率。
绘制异常和正常情况的概率密度:
abnormal = train.loc[train['异常']==1, '订单金额']
normal = train.loc[train['异常'==0], '订单金额']
绘制密度分布图
plt.figure(figsize=(10, 8), dpi=80)
sns.kdeplot(normal,
shade=True,
color="#01a2d9",
label="normal",
alpha=.5) #透明度
sns.kdeplot(abnormal,
shade=True,
color="#dc2624",
label="abnormal",
alpha=.9)
#风格与装饰
sns.set(style="whitegrid",font="SimHei", font_scale=1.1)
plt.title("abnormal vs normal the pic of money",fontsize=18)
#plt.yticks([])
# 可以通过这个具体看每个分段的具体分布
plt.xlim((0, 100))
plt.ylim((0,0.000002))
plt.show()
特征分箱
from sklearn.preprocessing import KBinsDiscretizer as KBD
def getColumnBinsDiscretizer(train, test, curColumnName, newColumnName, bins):
# 编码方式为顺序编码,策略为kmeans,分了10个箱
enc = KBD(n_bins=bins, encode='ordinal', strategy='kmeans')
enc = enc.fit(pd.DataFrame(train[curColumnName]))
# 进行新特征的赋值
train[newColumnName] = enc.transform(pd.DataFrame(train[curColumnName]))
test[newColumnName] = enc.transform(pd.DataFrame(test[curColumnName]))
return train, test
# 创建字典
def createNewFeature(train, test, groupbyColumnName, labelColumnName, newColumnName):
# 构造字典
dic = dict(train.groupby(groupbyColumnName)[labelColumnName].mean())
# train和test更新特征列
train[newColumnName] = train[groupbyColumnName].map(dic)
test[newColumnName] = test[groupbyColumnName].map(dic)
return train, test
创建二值分箱:
这个针对的特征是,在一定范围内无法区分是异常还是非异常,在阈值外大部分是异常可使用简单二值分箱
'''
对某一特征进行二值分析
'''
def createBinaryFeature(train, test, curColumnName, newColumnName, threshold):
# 增加新列并且设置初始值
train[newColumnName] = 0
test[newColumnName] = 0
#将满足指定阈值的
train.loc[train[curColumnName] > threshold, newColumnName] = 1
test.loc[test[curColumnName] > threshold, newColumnName] = 1
return train, test
pandas数据分析常用函数总结(下篇) - 知乎 (zhihu.com))
[国美在线商城异常订单检测](国美线上商城的异常订单检测 - Heywhale.com)