㈠ 如何用python新建一个1至100范围内的随机整数数组,其shape为(5,4),命名为data
from random import randint
ar=[[randint(1,100) for _ in range(4)] for _ in range(5)]
print(ar)
㈡ python 如何画出KD数
简单的KNN算法在为每个数据点预测类别时都需要遍历整个训练数据集来求解距离,这样的做法在训练数据集特别大的时候并不高效,一种改进的方法就是使用kd树来存储训练数据集,这样可以使KNN分类器更高效。
KD树的主要思想跟二叉树类似,我们先来回忆一下二叉树的结构,二叉树中每个节点可以看成是一个数,当前节点总是比左子树中每个节点大,比右子树中每个节点小。而KD树中每个节点是一个向量(也可能是多个向量),和二叉树总是按照数的大小划分不同的是,KD树每层需要选定向量中的某一维,然后根据这一维按左小右大的方式划分数据。在构建KD树时,关键需要解决2个问题:(1)选择向量的哪一维进行划分(2)如何划分数据。第一个问题简单的解决方法可以是选择随机选择某一维或按顺序选择,但是更好的方法应该是在数据比较分散的那一维进行划分(分散的程度可以根据方差来衡量)。好的划分方法可以使构建的树比较平衡,可以每次选择中位数来进行划分,这样问题2也得到了解决。下面是建立KD树的Python代码:
def build_tree(data, dim, depth):
"""
建立KD树
Parameters
----------
data:numpy.array
需要建树的数据集
dim:int
数据集特征的维数
depth:int
当前树的深度
Returns
-------
tree_node:tree_node namedtuple
树的跟节点
"""
size = data.shape[0]
if size == 0:
return None
# 确定本层划分参照的特征
split_dim = depth % dim
mid = size / 2
# 按照参照的特征划分数据集
r_indx = np.argpartition(data[:, split_dim], mid)
data = data[r_indx, :]
left = data[0: mid]
right = data[mid + 1: size]
mid_data = data[mid]
# 分别递归建立左右子树
left = build_tree(left, dim, depth + 1)
right = build_tree(right, dim, depth + 1)
# 返回树的根节点
return Tree_Node(left=left,
right=right,
data=mid_data,
split_dim=split_dim)
对于一个新来的数据点x,我们需要查找KD树中距离它最近的节点。KD树的查找算法还是和二叉树查找的算法类似,但是因为KD树每次是按照某一特定的维来划分,所以当从跟节点沿着边查找到叶节点时候并不能保证当前的叶节点就离x最近,我们还需要回溯并在每个父节点上判断另一个未查找的子树是否有可能存在离x更近的点(如何确定的方法我们可以思考二维的时候,以x为原点,当前最小的距离为半径画园,看是否与划分的直线相交,相交则另一个子树中可能存在更近的点),如果存在就进入子树查找。
当我们需要查找K个距离x最近的节点时,我们只需要维护一个长度为K的优先队列保持当前距离x最近的K个点。在回溯时,每次都使用第K短距离来判断另一个子节点中是否存在更近的节点即可。下面是具体实现的python代码:
def search_n(cur_node, data, queue, k):
"""
查找K近邻,最后queue中的k各值就是k近邻
Parameters
----------
cur_node:tree_node namedtuple
当前树的跟节点
data:numpy.array
数据
queue:Queue.PriorityQueue
记录当前k个近邻,距离大的先输出
k:int
查找的近邻个数
"""
# 当前节点为空,直接返回上层节点
if cur_node is None:
return None
if type(data) is not np.array:
data = np.asarray(data)
cur_data = cur_node.data
# 得到左右子节点
left = cur_node.left
right = cur_node.right
# 计算当前节点与数据点的距离
distance = np.sum((data - cur_data) ** 2) ** .5
cur_split_dim = cur_node.split_dim
flag = False # 标记在回溯时是否需要进入另一个子树查找
# 根据参照的特征来判断是先进入左子树还是右子树
if data[cur_split_dim] > cur_data[cur_split_dim]:
tmp = right
right = left
left = tmp
# 进入子树查找
search_n(left, data, queue, k)
# 下面是回溯过程
# 当队列中没有k个近邻时,直接将当前节点入队,并进入另一个子树开始查找
if len(queue) < k:
neg_distance = -1 * distance
heapq.heappush(queue, (neg_distance, cur_node))
flag = True
else:
# 得到当前距离数据点第K远的节点
top_neg_distance, top_node = heapq.heappop(queue)
# 如果当前节点与数据点的距离更小,则更新队列(当前节点入队,原第k远的节点出队)
if - 1 * top_neg_distance > distance:
top_neg_distance, top_node = -1 * distance, cur_node
heapq.heappush(queue, (top_neg_distance, top_node))
# 判断另一个子树内是否可能存在跟数据点的距离比当前第K远的距离更小的节点
top_neg_distance, top_node = heapq.heappop(queue)
if abs(data[cur_split_dim] - cur_data[cur_split_dim]) < -1 * top_neg_distance:
flag = True
heapq.heappush(queue, (top_neg_distance, top_node))
# 进入另一个子树搜索
if flag:
search_n(right, data, queue, k)525354555657
以上就是KD树的Python实践的全部内容,由于本人刚接触python不久,可能实现上并不优雅,也可能在算法理解上存在偏差,如果有任何的错误或不足,希望各位赐教。
㈢ 怎样用python构建一个卷积神经网络
用keras框架较为方便
首先安装anaconda,然后通过pip安装keras
㈣ python接口中net.blobs.data.shape 是怎么调用的
import numpya = numpy.array([[1,2,3],[4,5,6]])print a.shape矩阵有一个shape属性,是一个(行,列)形式的元组
㈤ python自带及pandas、numpy数据结构(一)
1.python自带数据结构:序列(如list)、映射(如字典)、集合(set)。
以下只介绍序列中的list:
创建list:
list1 = []
list1 = [1,2,3,4,5,6,7,8,9] #逗号隔开
list2 = [[1,2],[3,4],[5,6],[7,8]] #list2长度(len(list2))为2,list2[0] = [1,2]
liststring = list(“thisisalist”) #只用于创建字符串行表
索引list:
e = list1[0] #下标从零开始,用中括号
分片list:
es = list1[0:3]
es = list1[0:9:2] #步长在第二个冒号后
list拼接(list1.append(obj)、加运算及乘运算):
list长度:
list每个元素乘一个数值:
list2 = numpy.dot(list2,2)
list类似矩阵相乘(每个元素对应相乘取和):
list3 = numpy.dot(list1,list1)
#要求相乘的两个list长度相同
list3 = numpy.dot(list2,list22)
#要求numpy.shape(list2)和numpy.shape(list22)满足“左行等于右列”的矩阵相乘条件,相乘结果numpy.shape(list3)满足“左列右行”
2.numpy数据结构:
Array:
产生array:
data=np.array([[1, 9, 6], [2, 8, 5], [3, 7, 4]])
data=np.array(list1)
data1 = np.zeros(5) #data1.shape = (5,),5列
data1 = np.eye(5)
索引array:
datacut = data[0,2] #取第零行第二列,此处是6
切片array:
datacut = data[0:2,2] # array([6, 5])
array长度:
data.shape
data.size
np.shape(data)
np.size(data)
len(data)
array拼接:
#括号内也有一个括号(中括号或者小括号)!
d = np.concatenate((data,data))
d = np.concatenate((data,data),axis = 1) #对应行拼接
array加法:逐个相加
array乘法:
d = data data #逐个相乘
d = np.dot(data,data) #矩阵相乘
d = data 3 #每个元素乘3
d = np.dot(data,3) #每个元素乘3
array矩阵运算:
取逆 : np.linalg.inv(data)
转置:data.T
所有元素求和 : np.sum(data)
生成随机数:np.random.normal(loc=0, scale=10, size=None)
生成标准正态分布随机数组:np.random.normal(size=(4,4))
生成二维随机数组:
np.random.multivariate_normal([0,0],np.eye(2))
生成范围在0到1之间的随机矩阵(M,N):
np.random.randint(0,2,(M,N))
Matrix:
创建matrix:
mat1 = np.mat([[1, 2, 3], [4, 5, 6]])
mat1 = np.mat(list)
mat1 = np.mat(data)
matrix是二维的,所有+,-,*都是矩阵操作。
matrix索引和分列:
mat1[0:2,1]
matrix转置:
np.transpose(mat1)
mat1.transpose()
matrix拼接:
np.concatenate([mat1,mat1])
np.concatenate([mat1,mat1],axis = 1)
numpy数据结构总结:对于numpy中的数据结构的操作方法基本相同:
创建:np.mat(list),np.array(list)
矩阵乘:np.dot(x,y)
转置:x.T or np.transpose(x)
拼接:np.concatenate([x,y],axis = 1)
索引:mat[0:1,4],ary[0:1,4]
3.pandas数据结构:
Series:
创建series:
s = pd.Series([[1,2,3],[4,5,6]],index = [‘a’,‘b’])
索引series:
s1 = s[‘b’]
拼接series:
pd.concat([s1,s1],axis = 1) #也可使用s.append(s)
DataFrame:
创建DaraFrame:
df = pd.DataFrame([[1,2,3],[1,2,3]],index = ['a','b'],columns = ['x','y','z'])
df取某一列:
dfc1 =df.x
dfc1 = df[‘x’]
dfc2 = df.iloc[:,0] #用.iloc方括号里是数字而不是column名!
dfc2 = df.iloc[:,0:3]
df取某一行:
dfr1 = df.iloc[0]
df1 = df.iloc[0:2]
df1 = df[0:2] #这种方法只能用于取一个区间
df取某个值:
dfc2 = df.iloc[0,0]
dfc2 = df.iloc[0:2,0:3]
㈥ PYTHON实现对CSV文件多维不同单位数据的归一化处理
1)线性归一化
这种归一化比较适用在数值比较集中的情况,缺陷就是如果max和min不稳定,很容易使得归一化结果不稳定,使得后续的效果不稳定,实际使用中可以用经验常量来代替max和min。
2)标准差标准化
经过处理的数据符合标准正态分布,即均值为0,标准差为1。
3)非线性归一化
经常用在数据分化较大的场景,有些数值大,有些很小。通过一些数学函数,将原始值进行映射。该方法包括log、指数、反正切等。需要根据数据分布的情况,决定非线性函数的曲线。
log函数:x = lg(x)/lg(max)
反正切函数:x = atan(x)*2/pi
Python实现
线性归一化
定义数组:x = numpy.array(x)
获取二维数组列方向的最大值:x.max(axis = 0)
获取二维数组列方向的最小值:x.min(axis = 0)
对二维数组进行线性归一化:
def max_min_normalization(data_value, data_col_max_values, data_col_min_values):
""" Data normalization using max value and min value
Args:
data_value: The data to be normalized
data_col_max_values: The maximum value of data's columns
data_col_min_values: The minimum value of data's columns
"""
data_shape = data_value.shape
data_rows = data_shape[0]
data_cols = data_shape[1]
for i in xrange(0, data_rows, 1):
for j in xrange(0, data_cols, 1):
data_value[i][j] = \
(data_value[i][j] - data_col_min_values[j]) / \
(data_col_max_values[j] - data_col_min_values[j])
标准差归一化
定义数组:x = numpy.array(x)
获取二维数组列方向的均值:x.mean(axis = 0)
获取二维数组列方向的标准差:x.std(axis = 0)
对二维数组进行标准差归一化:
def standard_deviation_normalization(data_value, data_col_means,
data_col_standard_deviation):
""" Data normalization using standard deviation
Args:
data_value: The data to be normalized
data_col_means: The means of data's columns
data_col_standard_deviation: The variance of data's columns
"""
data_shape = data_value.shape
data_rows = data_shape[0]
data_cols = data_shape[1]
for i in xrange(0, data_rows, 1):
for j in xrange(0, data_cols, 1):
data_value[i][j] = \
(data_value[i][j] - data_col_means[j]) / \
data_col_standard_deviation[j]
非线性归一化(以lg为例)
定义数组:x = numpy.array(x)
获取二维数组列方向的最大值:x.max(axis=0)
获取二维数组每个元素的lg值:numpy.log10(x)
获取二维数组列方向的最大值的lg值:numpy.log10(x.max(axis=0))
对二维数组使用lg进行非线性归一化:
def nonlinearity_normalization_lg(data_value_after_lg,
data_col_max_values_after_lg):
""" Data normalization using lg
Args:
data_value_after_lg: The data to be normalized
data_col_max_values_after_lg: The maximum value of data's columns
"""
data_shape = data_value_after_lg.shape
data_rows = data_shape[0]
data_cols = data_shape[1]
for i in xrange(0, data_rows, 1):
for j in xrange(0, data_cols, 1):
data_value_after_lg[i][j] = \
data_value_after_lg[i][j] / data_col_max_values_after_lg[j]
㈦ Python对数据进行排序-中英文
sort_values(by,axis=0,ascending=True,inplace=False,kind='quicksort',na_position='last')
参数说明:
by: 可以填入字符串或者字符串组成的列表。也就是说, 如果axis=0,那么by="列名";如果axis=1,那么by="行名"。
axis: {0 or ‘index’, 1 or ‘columns’}, default 0,意思就是如果 axis=0,就按照索引排序,即纵向排序;如果axis=1,则按列排序,即横向排序。默认是axis=0 。
ascending: 输入布尔型, True是升序 , False是降序 ,也可以可以是[True,False],即第一个字段升序,第二个字段降序 。
inplace : 输入布尔型,是否用排序后的数据框替换现有的数据框
kind: 排序的方法,{‘quicksort’, ‘mergesort’, ‘heapsort’},默认是使用‘quicksort’。这个参数用的比较少,大家可以试一试。
na_position : {‘first’, ‘last’}, 缺失值的排序 ,也就说决定将缺失值放在数据的最前面还是最后面 。first是排在前面,last是排在后面,默认是用last 。
例子:
scores= pd.DataFrame([[87,56,85],[46,87,97],[34,65,86]],columns=['jack', 'rose', 'mike'])
scores
1.对‘rose’这一列进行降序排序:
df_sc=scores.sort_values(by='rose',ascending=False)
df_sc
2.对第0行进行升序排序:
scores.sort_values(by=0,axis=1,ascending=True)
3.第1行进行升序,第0行进行降序:
scores.sort_values(by=[1,0],axis=1,ascending=[True,False]
4.观察数据
data.head:
查看数据的前五行。
data.tail:
查看数据的后五行。
data.shape :
查看矩阵或数组的维数,或者是说数据表的结构(有几行几列)。
data.info :
查看数据的基本信息,如:数据类型、缺失值数量等。
#brand目标:中文-中英-英文
2.1 包含中文,纯英文
for i in range(0,len(file1)):
result = re.compile(u'[\u4e00-\u9fa5]')
contents = file1['brand'][i]
match = result.search(contents)
if match:
file1.loc[i,['index1']]=0 #0为包含中文
else:
file1.loc[i,['index1']]=1 #1为纯英文
2.1 包含英文,纯中文
for i in range(0,len(file1)):
file1.loc[i,['index2']]=len(re.findall('[a-zA-Z]+', file1['brand'][i]) ) #0为纯中文,1为包含英文
㈧ 如何使用Python工具分析风险数据
1、引入工具–加载数据分析包
启动IPython notebook,加载运行环境:
%matplotlib inline
import pandas as pd
from datetime import timedelta, datetime
import matplotlib.pyplot as plt
import numpy as np
2、数据准备
俗话说: 巧妇难为无米之炊。小安分析的数据主要是用户使用代理IP访问日志记录信息,要分析的原始数据以CSV的形式存储。这里首先要介绍到pandas.read_csv这个常用的方法,它将数据读入DataFrame
analysis_data = pd.read_csv('./honeypot_data.csv')
对的, 一行代码就可以将全部数据读到一个二维的表结构DataFrame变量,感觉很简单有木有啊!!!当然了用Pandas提供的IO工具你也可以将大文件分块读取,再此小安测试了一下性能,完整加载约21530000万条数据也大概只需要90秒左右,性能还是相当不错。
3、数据管窥
一般来讲,分析数据之前我们首先要对数据有一个大体上的了解,比如数据总量有多少,数据有哪些变量,数据变量的分布情况,数据重复情况,数据缺失情况,数据中异常值初步观测等等。下面小安带小伙伴们一起来管窥管窥这些数据。
使用shape方法查看数据行数及列数
analysis_data.shape
Out: (21524530, 22) #这是有22个维度,共计21524530条数据记的DataFrame
使用head()方法默认查看前5行数据,另外还有tail()方法是默认查看后5行,当然可以输入参数来查看自定义行数
analysis_data.head(10)
这里可以了解到我们数据记录有用户使用代理IP日期,代理header信息,代理访问域名,代理方法,源ip以及蜜罐节点信息等等。在此小安一定一定要告诉你,小安每次做数据分析时必定使用的方法–describe方法。pandas的describe()函数能对数据进行快速统计汇总:
对于数值类型数据,它会计算出每个变量: 总个数,平均值,最大值,最小值,标准差,50%分位数等等;
非数值类型数据,该方法会给出变量的: 非空值数量、unique数量(等同于数据库中distinct方法)、最大频数变量和最大频数。
由head()方法我们可以发现数据中包含了数值变量、非数值变量,我们首先可以利用dtypes方法查看DataFrame中各列的数据类型,用select_dtypes方法将数据按数据类型进行分类。然后,利用describe方法返回的统计值对数据有个初步的了解:
df.select_dtypes(include=['O']).describe()
df.select_dtypes(include=['float64']).describe()
简单的观察上面变量每一维度统计结果,我们可以了解到大家获取代理数据的长度平均1670个字节左右。同时,也能发现字段scanossubfp,scanscan_mode等存在空值等等信息。这样我们能对数据整体上有了一个大概了解。
4、数据清洗
由于源数据通常包含一些空值甚至空列,会影响数据分析的时间和效率,在预览了数据摘要后,需要对这些无效数据进行处理。
一般来说,移除一些空值数据可以使用dropna方法, 当你使用该方法后,检查时发现 dropna() 之后几乎移除了所有行的数据,一查Pandas用户手册,原来不加参数的情况下, dropna() 会移除所有包含空值的行。
如果你只想移除全部为空值的列,需要加上 axis 和 how 两个参数:
analysis_data.dropna(axis=1, how='all')
另外,也可以通过dropna的参数subset移除指定列为空的数据,和设置thresh值取移除每非None数据个数小于thresh的行。
analysis_data.dropna(subset=['proxy_host', 'srcip'])
#移除proxy_host字段或srcip字段没有值的行
analysis_data.dropna(thresh=10)
#移除所有行字段中有值属性小于10的行
5、统计分析
再对数据中的一些信息有了初步了解过后,原始数据有22个变量。从分析目的出发,我将从原始数据中挑选出局部变量进行分析。这里就要给大家介绍pandas的数据切片方法loc。
loc([startrowindex:endrowindex,[‘timestampe’, ‘proxy_host’, ‘srcip’]])是pandas重要的切片方法,逗号前面是对行进行切片;逗号后的为列切片,也就是挑选要分析的变量。
如下,我这里选出日期,host和源IP字段——
analysis_data = analysis_data.loc([:, [‘timestampe’,'proxy_host','srcip']])
首先让我们来看看蜜罐代理每日使用数据量,我们将数据按日统计,了解每日数据量PV,并将结果画出趋势图。
daily_proxy_data = analysis_data[analysis_data.mole=='proxy']
daily_proxy_visited_count = daily_proxy_data.timestamp.value_counts().sort_index()
daily_proxy_visited_count.plot()
对数据列的丢弃,除无效值和需求规定之外,一些表自身的冗余列也需要在这个环节清理,比如说DataFrame中的index号、类型描述等,通过对这些数据的丢弃,从而生成新的数据,能使数据容量得到有效的缩减,进而提高计算效率。
由上图分析可知蜜罐代理使用量在6月5号,19-22号和25号这几天呈爆炸式增长。那么这几天数据有情况,不正常,具体是神马情况,不急,后面小安带大家一起来慢慢揪出来到底是那些人(源ip) 干了什么“坏事”。
进一步分析, 数据有异常后,再让我们来看看每天去重IP数据后量及其增长量。可以按天groupby后通过nunique()方法直接算出来每日去重IP数据量。
daily_proxy_data = analysis_data[analysis_data.mole=='proxy']
daily_proxy_visited_count = daily_proxy_data.groupby(['proxy_host']).srcip.nunique()
daily_proxy_visited_count.plot()
究竟大部分人(源ip)在干神马?干神马?干神马?让我们来看看被访问次数最多host的哪些,即同一个host关联的IP个数,为了方便我们只查看前10名热门host。
先选出host和ip字段,能过groupby方法来group 每个域名(host),再对每个域名的ip访问里unique统计。
host_associate_ip = proxy_data.loc[:, ['proxy_host', 'srcip']]
grouped_host_ip = host_associate_ip.groupby(['proxy_host']).srcip.nunique()
print(grouped_host_ip.sort_values(ascending=False).head(10))
再细细去看大家到底做了啥——查看日志数据发现原来在收集像二手车价格,工人招聘等等信息。从热门host来看,总得来说大家使用代理主要还是获取网络,qq,Google,Bing这类妇孺皆知网站的信息。
下面再让我们来看看是谁用代理IP“干事”最多,也就是看看谁的IP访问不同host的个数最多。
host_associate_ip = proxy_data.loc[:, ['proxy_host', 'srcip']]
grouped_host_ip = host_associate_ip.groupby(['srcip'_host']).proxy_host.nunique()
print(grouped_host_ip.sort_values(ascending=False).head(10))
哦,发现目标IP为123..*.155的小伙子有大量访问记录, 进而查看日志,原来他在大量收集酒店信息。 好了,这样我们就大概能知道谁在干什么了,再让我们来看看他们使用proxy持续时长,谁在长时间里使用proxy。 代码如下——
这里不给大家细说代码了,只给出如下伪代码。
date_ip = analysis_data.loc[:,['timestamp','srcip']]
grouped_date_ip = date_ip.groupby(['timestamp', 'srcip'])
#计算每个源ip(srcip)的访问日期
all_srcip_ration_times = ...
#算出最长连续日期天数
ration_date_cnt = count_date(all_srcip_ration_times)
好了,到此我也就初略的知道那些人做什么,谁用代理时长最长等等问题额。取出ip = 80...38的用户使用代理ip访问数据日志,发现原来这个小伙子在长时间获取搜狐images。
蜜罐在全国各地部署多个节点,再让我们来看看每个源ip扫描蜜罐节点总个数,了解IP扫描节点覆盖率。结果见如下:
# 每个IP扫描的IP扫描节点总个数
node = df[df.mole=='scan']
node = node.loc[:,['srcip','origin_details']]
grouped_node_count = node.groupby(['srcip']).count()
print grouped_node_count.sort_values(['origin_details'], ascending=False).head(10)
由上述两表初步可知,一些结论:如源ip为182...205的用户长时间对蜜罐节点进行扫描,mark危险用户等等。