利用Python通过频谱分析和KNN完成iphone拨号的语音识别

2023-11-03

最近这段时间,学校里的事情实在太多了,从七月下旬一直到八月底实验室里基本天天十二点或者通宵,实在是没有精力和时间来写博客。这周老师出国开会,也算有了一个短暂的休息机会,刚好写点有意思的东西。

上周在天津的会议上碰到一个北交的姐们儿,她想利用小波变换来处理失超信号,刚好之前自己就有这个想法,所以回来后就想着把相关的内容好好复习复习,最相关的就是傅里叶分析和小波变换了。数学推导固然重要,但写那个实在是太乏味了,然后想到之前网上一个新闻,说一个同学通过新闻里记者拨号的声音反推出了周鸿祎的手机号码,就想着能不能自己也做一个这样的号码识别程序呢?

说做就做,首先整理一下思路,我觉得大概的流程应该包括一下几步:

1 单键声音的采集与分析

这是后面号码识别的基础,针对每个按键音分析其在频域上的分布规律进而得到一个基准,后面再采集到的声音可据此进行判定。

2 声音的降噪

自己录的这些声音总不会太完美,直接进行频谱分析,会得到一个非常杂乱的结果,所以有效的声音降噪可以帮助我们更加精确地进行判断。

3 号码识别思路

我想的方案主要是两种,刚好也符合我最近复习的这两种变换

A 对声音文件进行有效区域划分,然后对每个区域单独进行频谱分析,然后比对训练数据,推断每一处对应的号码,最后输出。

B 采用小波分析,输出对应声音文件的小波时频图,观察其在不同时刻频域各处强度的变化,进而确定所拨的号码。

两种方案我感觉应该都可以,不过第一种感觉相对要简单一点,所以我们就先来试试第一个。

Ok,那第一步我们得先找到合适的单个按键音数据,这个上网一搜iphone按键音就找到了,下载下来发现刚好又是wav文件,可以用Python自带的wave库直接处理,简直美滋滋。

简单说一下wave库,用它读取一个wave文件后,我们可以获取四个参数,包括通道数目,样本宽度,采样率以及采样数目。根据通道数目,你可以确定是单通道和双通道,如果是单通道你直接读取采样文件就行,但如果是双通道,采样是一左一右轮着来的,所以到时候你还得把它分成两列,然后选择其中一列来读。从网上下载的这些音源刚好是单声道的,所以直接读取就行了,下面以0为例,读取它的波形并画出来。

import numpy as np
import wave
from matplotlib import pyplot as plt
file_path='C:\Users\**\Desktop\iphone\dtmf-0.wav'
f=wave.open(file_path,'rb')
num=file_path[-5] 
params=f.getparams()
nchannels,samplewidth,framerate,nframes=params[:4]
str_data=f.readframes(nframes)
f.close()
wave_data=np.fromstring(str_data,dtype=np.short)
wave_data.shape=-1,1
if nchannels==2:
    wave_data.shape=-1,2
else:
    pass
wave_data=wave_data.T
time=np.arange(0,nframes)*(1.0/framerate)
plt.subplot(211)
plt.plot(time,wave_data[0],'r-')
plt.xlabel('Time/s')
plt.ylabel('Ampltitude')
plt.title('Num '+num+' time/ampltitude')
plt.show()

结果如下


其实波形看起来还是比较规律的,但明显是有不同频率的波叠加在一起,所以下一步我们采用傅里叶分析,看看它在频域上是什么样的。Python中进行傅里叶分析是十分方便的,直接利用numpy中的fft就行,分解完成后,考虑到高频的成分不需要,所以选择4000做个阈值,超出这个区域的都舍掉。另外,因为目前我并不考虑信号的重构,所以我直接把对应频率的幅值去了绝对值,这样方便我下一步寻找波峰。完成这些操作后,画个频谱图看看有什么规律。

df=framerate/(nframes-1)
freq=[df*n for n in range(0,nframes)]
transformed=np.fft.fft(wave_data[0])
d=int(len(transformed)/2)
while freq[d]>4000:
    d-=10
freq=freq[:d]
transformed=transformed[:d]
for i,data in enumerate(transformed):
    transformed[i]=abs(data)
plt.subplot(212)
plt.plot(freq,transformed,'b-')
plt.xlabel('Freq/Hz')
plt.ylabel('Ampltitude')
plt.title('Num '+num+' freq/ampltitude')
plt.show()

结果如下


哎呀我去,这也太完美了吧……我都怀疑下的这些波形文件是电脑写的,也太规整了,仅在两个频率处出现了峰值,其余处为0,感觉事情并不简单,上网查了一圈发现Iphone的按键音采用的是DTMF,双音多频,每个按键音都是一个高频加一个低频信号的叠加。原来如此,那我就放心继续做下去了。那么下一步是提取这两个频率值,上面我已经说了,为了方便我寻找这两个波峰,我已经将平率对应幅度全部取绝对值,现在其实就是找到两个局部极值对应的频率就好。那首先找到两个极大值,然后确定它们的位置再对应到频域上就OK,代码如下

local_max=[]
for i in np.arange(1,len(transformed)-1):
    if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:
        local_max.append(transformed[i])
local_max=sorted(local_max)
loc1=np.where(transformed==local_max[-1])
max_freq=freq[loc1[0][0]]
loc1=np.where(transformed==local_max[-2])
min_freq=freq[loc1[0][0]]
print 'Two freq ',max_freq,min_freq

结果如下

Two freq  1278 900

好的,针对一个数字的音频分析完成了,那其他的数字也如法炮制,定义一个函数,再用个循环就好,最后把这些数字所对应的频率画在图上,整体代码如下:

import wave
import numpy as np
from matplotlib import pyplot as plt

def wave_analysis(file_path):
    f=wave.open(file_path,'rb')
    num=file_path[-5] 
    params=f.getparams()
    nchannels,samplewidth,framerate,nframes=params[:4]
    str_data=f.readframes(nframes)
    f.close()
    wave_data=np.fromstring(str_data,dtype=np.short)
    wave_data.shape=-1,1
    if nchannels==2:
        wave_data.shape=-1,2
    else:
        pass
    wave_data=wave_data.T
    time=np.arange(0,nframes)*(1.0/framerate)
    plt.subplot(211)
    plt.plot(time,wave_data[0],'r-')
    plt.xlabel('Time/s')
    plt.ylabel('Ampltitude')
    plt.title('Num '+num+' time/ampltitude')
    plt.show()
    df=framerate/(nframes-1)
    freq=[df*n for n in range(0,nframes)]
    transformed=np.fft.fft(wave_data[0])
    d=int(len(transformed)/2)
    while freq[d]>4000:
        d-=10
    freq=freq[:d]
    transformed=transformed[:d]
    for i,data in enumerate(transformed):
        transformed[i]=abs(data)
    plt.subplot(212)
    plt.plot(freq,transformed,'b-')
    plt.xlabel('Freq/Hz')
    plt.ylabel('Ampltitude')
    plt.title('Num '+num+' freq/ampltitude')
    local_max=[]
    for i in np.arange(1,len(transformed)-1):
        if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:
            local_max.append(transformed[i])
    local_max=sorted(local_max)
    loc1=np.where(transformed==local_max[-1])
    max_freq=freq[loc1[0][0]]
    loc1=np.where(transformed==local_max[-2])
    min_freq=freq[loc1[0][0]]
    plt.show()
    print 'Two freq ',max_freq,min_freq
    return max_freq,min_freq
    

def main():
    x=[]
    y=[]
    for i in np.arange(0,10):
        path='C:\Users\**\Desktop\iphone\dtmf-'+str(i)+'.wav'
        max_freq,min_freq=wave_analysis(path)
        x.append(i)
        y.append(max_freq)
        x.append(i)
        y.append(min_freq)
    plt.scatter(x,y,marker='*')
    plt.show()

if __name__=='__main__':
    main()

中间的振幅和频域的图就不贴了,就看一下最后一张每个数字所对应的特定频率图


把数字填到表格里是这样

0

1

2

3

4

5

6

7

8

9

900

640

649

664

744

711

686

784

760

810

1278

1110

1243

1408

1168

1233

1316

1112

1192

1404

其实规律还是很容易看出来的,每个按键音对应于一个高频和一个低频,其中,123,456,789的低频部分相似,147,258,369的高频部分相似,这和DTMF是一致的,从百科上扒了一张图,大家可以对比一下


展现出来的规律是相似的,但数值并不完全一样,我们计算出来的似乎有那么一点点偏小,但这并不重要,赶紧拿个实际录音来看看吧。

先录了10个单音,看看频谱分析怎么样,完全同样的方法,针对数字0,结果如下



Two freq  1283 1270

发现问题了没

1 录音的数据并不是全程都是按键音,很大一部分是无用的,整体进行傅里叶分析会产生非常大的干扰信号

2 录音的数据里叠加有很多噪声,导致频域分布复杂。

3 频域信号里有很多的毛刺,这样导致产生了很多局部极大值,导致我们之前用的寻找波峰的算法失效。

OKOK,那我们一步步来解决问题。

首先第一个相当于就是有效波形的提取了。高级的方法我也不会啊,但就直观来看,明显有效区域的波形幅度远大于无效区,那我们是不是可以取个阈值,从第一个超过该阈值的开始记为起始点,然后连续超过多少个点都小于阈值后记为终止点,当然可以,在这里我选择的阈值是最大值的5%,事实表明这样还是很有效的。

那对与第二个问题,其实噪声很多都是高频的,首先滤除高频部分是一个选项,其次即使是噪声,它往往也是周期性的,一个周期内的噪声叠加起来往往为0,所以我们选一个时间窗口,进行移动平均,这样可以有效的消除噪声的影响。同时,这也能解决第三步遇到的问题,移动平均最大的好处就是会使曲线变得光滑,不会出现很多的毛刺,这样通过移动平均处理后的频域图又可以重新使用我们之前所说的寻找局部极值来确定频率的方法。哦,对了对了,移动平均可以通过卷积操作来实现,非常简单。代码如下

import wave
import numpy as np
from matplotlib import pyplot as plt
#load wave file and get params
file_path='C:\\Users\\**\\Desktop\\iphone\\Test\\0.wav'
f=wave.open(file_path,'rb')
#num=file_path[-5] 
num=str(0)
params=f.getparams()
nchannels,samplewidth,framerate,nframes=params[:4]
str_data=f.readframes(nframes)
f.close()
wave_data=np.fromstring(str_data,dtype=np.short)
wave_data.shape=-1,1
if nchannels==2:
    wave_data.shape=-1,2
else:
    pass
wave_data=wave_data.T
#moving average
def moving_average(data,n):
    weights=np.ones(n)
    weights/=weights.sum()
    ma=np.convolve(data,weights,mode='full')[:len(data)]
    ma[:n]=ma[n]
    return ma

new_data=moving_average(wave_data[0],10)
new_data=moving_average(new_data,10)
new_data_2=[]
max_wave=new_data.max()
#look for the start point and end point
index=0
flag=False
for i in np.arange(0,len(new_data)):
#    index=0
    if abs(new_data[i])>=0.05*max_wave:
        new_data_2.append(new_data[i])
        index=0
        if abs(new_data[i+1])<0.05*max_wave:
            for j in np.arange(1,40):
                if abs(new_data[i+1+j])<0.05*max_wave:
                    index+=1
                    if index>=39:
                        print index 
                        flag=True
                        break
    if flag==True:
        break
                

time=np.arange(0,len(new_data_2))*(1.0/framerate)
plt.subplot(211)
plt.plot(time,new_data_2,'r-')
plt.xlabel('Time/s')
plt.ylabel('Ampltitude')
plt.title('Num '+num+' time/ampltitude')
plt.show()
df=framerate/(len(new_data_2)-1)
freq=[df*n for n in range(0,len(new_data_2))]
transformed=np.fft.fft(new_data_2)
d=int(len(transformed)/2)
while freq[d]>2000:
    d-=10
freq=freq[:d]
transformed=transformed[:d]
for i,data in enumerate(transformed):
    transformed[i]=abs(data)
transformed=moving_average(transformed,5)
transformed=moving_average(transformed,5)
transformed=moving_average(transformed,5)    
plt.subplot(212)
plt.plot(freq,transformed,'b-')
plt.xlabel('Freq/Hz')
plt.ylabel('Ampltitude')
plt.title('Num '+num+' freq/ampltitude')
plt.show()
#look for local maximum
local_max=[]
for i in np.arange(1,len(transformed)-1):
    if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:
        local_max.append(transformed[i])
local_max=sorted(local_max)
loc1=np.where(transformed==local_max[-1])
freq1=freq[loc1[0][0]]
loc1=np.where(transformed==local_max[-2])
freq2=freq[loc1[0][0]]
    
            
print 'Two freq ',freq1,freq2

结果如下



Two freq  1368 981

蛤蛤蛤,perfect!!!有效信号的提取以及频谱分析都没有问题了,唯一的遗憾就是分解出来的两个频率值又和之前下载的版本不一致了,不过没关系,我们还是要相信实际结果。接下来依次对录的其他号码进行分析,得到新的各个号码对应两个频率值。

得到了所有号码对应的两个频率值之后,我们就可以对再采集的信号进行预测了。采用什么预测方法呢?在之前博客里写过很多很多分类方法,但我觉得都不用,为啥呢,训练数据太少了,算法再高级也没卵用,哎呀,好丧啊……那我们就用最朴素的方法吧,计算采样数据的两个频率与所有训练数据频率的距离,选择最小的那个作为输出,当然你也可以宣称用的是KNN算法,没毛病啊,就是最近邻呀……

回到最开始说的,我们想做的是一个语音号码识别,所以这里还要考虑一段数据包含多个按键音的有效区域提取,因为之前的算法时针对单音的。一开始我以为只要把之前的跳出循环操作改成保存数据,标记置0就OK,后来发现我实在是天真了,这样做的后果就是除了我们真实有效区域以外,偶尔有一个噪声超过阈值的也全都提取出来了。所以除了幅度阈值之外,我对提取的有效区域长度也做了一个限制,进而保提取的区域都是我们的目标区域。

至此,全部的问题都解决了,整合一下代码,最终如下

import wave
import numpy as np
from matplotlib import pyplot as plt

#moving average
def moving_average(data,n):
    weights=np.ones(n)
    weights/=weights.sum()
    ma=np.convolve(data,weights,mode='full')[:len(data)]
    ma[:n]=ma[n]
    return ma


        
#get wave data
def get_wave_data(file_path):
    f=wave.open(file_path,'rb')
    params=f.getparams()
    nchannels,samplewidth,framerate,nframes=params[:4]
    str_data=f.readframes(nframes)
    f.close()
    wave_data=np.fromstring(str_data,dtype=np.short)
    wave_data.shape=-1,1
    if nchannels==2:
        wave_data.shape=-1,2
    else:
        pass
    wave_data=wave_data.T
    return wave_data[0],framerate

#find the efficient area in wave
def find_efficient_area(wave_data):
    wave_data=moving_average(wave_data,10)
    wave_data=moving_average(wave_data,10)
    wave_data=moving_average(wave_data,10)
    wave_data=moving_average(wave_data,10)
    new_data=[]
    max_wave=wave_data.max()
    efficient_data=[]
    index=0
    count=0
    flag=False
    for i in np.arange(0,len(wave_data)):
        if abs(wave_data[i])>=0.05*max_wave:
            new_data.append(wave_data[i])
            index=0
            if i+1>=len(wave_data):
                break
            if abs(wave_data[i+1])<0.05*max_wave:
                for j in np.arange(1,60):
                    if i+1+j>=len(wave_data):
                        break
                    if abs(wave_data[i+1+j])<0.05*max_wave:
                        index+=1
                if index>=59: 
                    flag=True
                        
                
              
        if flag==True:
            if len(new_data)>2000:
#                plt.plot(new_data,'r-')
#                plt.show()
                efficient_data.append(new_data)
                count+=1
            new_data=[]
            index=0
            flag=False
    print 'Find ',count,' efficient wave'
    return efficient_data,count

#Analysis single wave data
def wave_analysis_single(efficient_data,framerate):
    time=np.arange(0,len(efficient_data[0]))*(1.0/framerate)
#    plt.plot(time,efficient_data[0],'r-')
#    plt.xlabel('Time/s')
#    plt.ylabel('Ampltitude')
#    plt.title(' time/ampltitude')
#    plt.show()
    df=framerate/(len(efficient_data[0])-1)
    freq=[df*n for n in range(0,len(efficient_data[0]))]
    transformed=np.fft.fft(efficient_data[0])
    d=int(len(transformed)/2)
    while freq[d]>2000:
        d-=10
    freq=freq[:d]
    transformed=transformed[:d]
    for i,data in enumerate(transformed):
        transformed[i]=abs(data)
    transformed=moving_average(transformed,5)
    transformed=moving_average(transformed,5)
    transformed=moving_average(transformed,5)
#    transformed=moving_average(transformed,5)
#    plt.plot(freq,transformed,'b-')
#    plt.xlabel('Freq/Hz')
#    plt.ylabel('Ampltitude')
#    plt.title(' freq/ampltitude')
#    plt.show()
    #look for local maximum
    local_max=[]
    for i in np.arange(1,len(transformed)-1):
        if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:
            local_max.append(transformed[i])
    local_max=sorted(local_max)
    loc1=np.where(transformed==local_max[-1])
    freq_1=freq[loc1[0][0]]
    loc1=np.where(transformed==local_max[-2])
    freq_2=freq[loc1[0][0]]
    print 'Frequency',freq_1,freq_2
    return freq_1,freq_2
        
        


#Get training data
train_data={}
for i in np.arange(0,10):
    file_path='C:\\Users\\**\\Desktop\\iphone\\Test\\'+str(i)+'.wav'
    wave_data,framerate=get_wave_data(file_path)
    data,count=find_efficient_area(wave_data)
    a,b=wave_analysis_single(data,framerate)
    train_data[i]=[a,b]



#multi_number estimate
def number_estimate(freq1,freq2):
    err=100000
    num=0
    for i in np.arange(0,10):
        tmp=(freq1-train_data[i][0])**2+(freq2-train_data[i][1])**2
        if tmp<err:
            err=tmp
            num=i
        else:
            pass
    return num
    
    
#Analysis multi wave data
def wave_analysis_multi(efficient_data,framerate):
    num=[]
    for data in efficient_data:
        time=np.arange(0,len(data))*(1.0/framerate)
        plt.plot(time,data,'r-')
        plt.xlabel('Time/s')
        plt.ylabel('Ampltitude')
        plt.title(' time/ampltitude')
        plt.show()
        df=framerate/(len(data)-1)
        freq=[df*n for n in range(0,len(data))]
        transformed=np.fft.fft(data)
        d=int(len(transformed)/2)
        while freq[d]>2000:
            d-=10
        freq=freq[:d]
        transformed=transformed[:d]
        for i,data in enumerate(transformed):
            transformed[i]=abs(data)
        transformed=moving_average(transformed,5)
        transformed=moving_average(transformed,5)   
        transformed=moving_average(transformed,5)
        plt.plot(freq,transformed,'b-')
        plt.xlabel('Freq/Hz')
        plt.ylabel('Ampltitude')
        plt.title(' freq/ampltitude')
        plt.show()
#        look for local maximum
        local_max=[]
        for i in np.arange(1,len(transformed)-1):
            if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:
                local_max.append(transformed[i])
        local_max=sorted(local_max)
        loc1=np.where(transformed==local_max[-1])
        freq_1=freq[loc1[0][0]]
        loc1=np.where(transformed==local_max[-2])
        freq_2=freq[loc1[0][0]]
        if freq_1<freq_2:
            freq_1,freq_2=freq_2,freq_1
        print freq_1,freq_2
        num.append(number_estimate(freq_1,freq_2))
        
    
    print num
        
file_path='C:\\Users\\**\Desktop\\iphone\\5201314999.wav'
wave_data,framerate=get_wave_data(file_path)
data,count=find_efficient_area(wave_data)
wave_analysis_multi(data,framerate)

结果如下

[2, 2, 8, 1, 6, 1, 4, 3, 9, 9]

家里领导很肉麻地录的是5201314999,结果出来效果真的很垃圾啊……不过想想这训练数据这么少,并且采用了那么朴素的判定方法,正确率高了才见鬼了好吧!!!

不过人的智慧是无穷的,通过改变数据移动平均的次数以及一个小trick

#A little trick
train_data[1][0]=train_data[4][0]=train_data[7][0]=(train_data[1][0]+train_data[4][0]+train_data[7][0])/3

train_data[3][0]=train_data[6][0]=train_data[9][0]=(train_data[3][0]+train_data[6][0]+train_data[9][0])/3
train_data[1][1]=train_data[2][1]=train_data[3][1]=(train_data[1][1]+train_data[2][1]+train_data[3][1])/3

train_data[7][1]=train_data[8][1]=train_data[9][1]=(train_data[7][1]+train_data[8][1]+train_data[9][1])/3

train_data[2][0]=train_data[5][0]=train_data[8][0]=train_data[0][0]=(train_data[1][0]+train_data[3][0])/2
train_data[4][1]=train_data[5][1]=train_data[6][1]=(train_data[1][1]+train_data[7][1])/2

再次进行预测,结果为

[5, 2, 0, 1, 3, 1, 4, 9, 9, 9]

蛤蛤蛤,很厉害有没有?!

屁啦,没有普适性,对预测能力并没有质的提高,这个trick可以用,但是对数据进行移动平均的次数真的对预测结果有很大影响。

好啦,至此,我们第一个语音号码识别程序的demo已经出来了,虽然正确率只有60%左右,但这是个十分类问题啊喂,比你乱猜还是靠谱多了好吗!!!当然,提高的空间还很大,大家如果有兴趣的可以一起讨论讨论,比如我觉得可以对从频谱中得到的数据依照训练数据做个拉普拉斯平滑~

这周花了很多时间在这个小玩意儿上,课题的东西一点也没干,感觉周一组会老板回来要GoDie了,好慌啊,先歇个周六压压惊,周末愉快各位,蛤蛤蛤~~~
















本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用Python通过频谱分析和KNN完成iphone拨号的语音识别 的相关文章

  • Windows 中的 Python 多处理池奇怪行为

    Python 多处理池在 Linux 和 Windows 之间有不同的行为 当按工作人员数量运行方法映射时 在 Linux 中 它会在您作为参数提供的特定函数的范围内运行该进程 但在 Windows 中 每个工作进程都在父进程的范围内运行
  • 将字符串转换为浮点数列表(在 python 中)

    出于数据存储的目的 我尝试从 txt 文件恢复浮点列表 从字符串中可以看出 a 1 3 2 3 4 5 我想恢复 a 1 3 2 3 4 5 我期待一个简单的解决方案 例如list a 但我找不到类似的东西 Use the AST模块 Ex
  • 从 asyncio 子进程获取实时输出

    我正在尝试使用 Python asyncio 子进程来启动交互式 SSH 会话并自动输入密码 实际用例并不重要 但它有助于说明我的问题 这是我的代码 proc await asyncio create subprocess exec ssh
  • 从 Python 中的 message_from_string() 获取发件人地址

    有人可以告诉我如何在Python中从email message from string 获取发件人地址吗 谢谢 我试过 message email message from string email text from message Fr
  • setColumnStretch 和 setRowStretch 如何工作

    我有一个使用构建的应用程序PySide2它使用setColumnStretch用于柱拉伸和setRowStretch用于行拉伸 它工作得很好 但我无法理解它是如何工作的 我参考了 qt 文档 但它对我没有帮助 我被困在括号内的两个值上 例如
  • Django 营业时间

    我想添加诊所的营业时间 我已经对此进行了调查在 Django 中实现 开放时间 的任何现有解决方案 https stackoverflow com questions 8128143 any existing solution to imp
  • 使用 pyppeteer 与 asyncio 关联来抓取内容

    我用 python 结合编写了一个脚本pyppeteer随着asyncio从其登陆页面抓取不同帖子的链接 并最终通过跟踪通向其内页的 url 来获取每个帖子的标题 我这里解析的内容不是动态的 但是 我利用了pyppeteer and asy
  • 清理 MongoDB 的输入

    我正在为 MongoDB 数据库程序编写 REST 接口 并尝试实现搜索功能 我想公开整个 MongoDB 接口 我确实有两个问题 但它们是相关的 所以我将它们放在一篇文章中 使用 Python json 模块解码不受信任的 JSON 是否
  • Python SQLite3 SQL注入漏洞代码

    我知道下面的代码片段由于 format 的原因很容易受到 SQL 注入的攻击 但我不知道为什么 有谁明白为什么这段代码容易受到攻击以及我从哪里开始修复它 我知道这些代码片段使输入字段保持打开状态 以便通过 SQL 注入执行其他恶意命令 但不
  • Python MySQLdb:connection.close() VS。光标.close()

    如果我使用MySQLdb通过Python连接到MySQL Server 我创建一个connection and a cursor像这样 connection MySQLdb connect cursor connection cursor
  • pandas DataFrame 中行的高效成对比较

    我目前正在处理一个较小的数据集 大约 900 万行 不幸的是 大多数条目都是字符串 即使强制类别 框架在内存中也只有几 GB 我想做的是将每一行与其他行进行比较 并对内容进行直接比较 例如 给定 A B C D 0 cat blue old
  • Python正则表达式替换引号中的文本(引号本身除外)

    例如 我有一个测试字符串 content I opened my mouth Good morning I said cheerfully 我想使用正则表达式删除双语音标记之间的文本 但不删除语音标记本身 所以它会返回 I opened m
  • 如何使用 Python 在表单中选择选项?

    我想知道如何以格式如下的形式选择选项 td align left td
  • Python 模块 BeautifulSoup 提取锚点 href

    我正在使用 BeautifulSoup 模块通过以下方式从 html 选择所有 href def extract links html soup BeautifulSoup html anchors soup findAll a print
  • python os.fork 使用相同的 python 解释器吗?

    据我所知 Python 中的线程使用相同的 Python 解释器实例 我的问题是与创建的流程相同os fork 或者每个进程创建的os fork有自己的翻译吗 每当你 fork 时 整个 Python 进程都会在内存中复制 包括Python
  • 如何在 Jupyter Notebook 中选择 conda 环境

    我安装了 Anaconda 5 3 和 Python 3 7 根环境 之后我使用 Python 3 6 创建了一个新环境 py36 我激活了新环境activate py36 conda env list表明环境是活跃的 但是当我启动 Jup
  • 从函数在 python 3 中创建全局变量

    我想知道为什么在函数结束后我无法访问变量 variable for raw data 代码是这样的 def htmlfrom Website URL import urllib request response urllib request
  • model.predict() 返回类而不是概率

    Hello 我是第一次使用 Keras 我训练并保存了一个模型 作为 json 文件及其权重 该模型旨在将图像分为 3 个类别 我的编译方法 model compile loss categorical crossentropy optim
  • 如何使用 QAbstractTableModel(模型/视图)将数据设置到 QComboBox?

    我希望能够设置itemData of a combobox当使用填充时QAbstractTableModel 但是 我只能从模型返回一个字符串data method 通常 当不使用模型时 可以像这样执行 Set text and data
  • 如何从 Pandas 数据框函数调用中回顾之前的行?

    我正在研究 回测交易系统 我有一个包含 OHLC 数据的 Pandas 数据框 并添加了几个计算列 https stackoverflow com questions 12376863 adding calculated columns t

随机推荐

  • 使用Simulink进行stm32开发2

    使用Simulink进行stm32开发2 小车直流电机控制 1 配置工程文件 simulink 模块搭建 stm32驱动模块 配置数据字典 配置电机控制函数 模块封装 加入输入并生成代码 基于对模型开发的学习 在这里用simulink搭建小
  • MyBatis 使用数组作为参数

  • OpenGL教程(五)

    前言 正如之前章节所提到的 着色器就是运行在GPU上的小程序 简单来说 着色器就是仅仅是一个将输入数据经过一定转换然后输出的过程 着色器之间是非常独立的 彼此之间除了输入输出之外没有其他交流 这篇文章将会详细介绍着色器以及编写着色器的语言G
  • 上下div之间有间距的问题

    我写了4个div 上下分布 均存在间距 代码以及效果如下 div1 height 100px background color blue position relative div2 height 100px background colo
  • HTTP请求方式中8种请求方法(简单介绍)

    HTTP请求方式中8种请求方法 简单介绍 简单介绍 HTTP是超文本传输协议 其定义了客户端与服务器端之间文本传输的规范 HTTP默认使用80端口 这个端口指的是服务端的端口 而客户端使用的端口是动态分配的 当我们没有指定端口访问时 浏览器
  • [Unity2D/3D]实用的血条制作(第一期)

    Unity2D 3D 实用的血条制作 第一期 在多数的游戏制作中 都会涉及到血条的制作 不论是在2D游戏中还是3D游戏中都非常常见 如何制作一款简易的血条呢 这里我给结合自己自学过程中用到的血条制作方法给大家分享一下我是如何制作血条的 效果
  • atoi函数(c语言)

    目录 atoi函数的说明 函数改编以及思路 代码 代码注释 atoi函数的说明 该函数的作用是将一字符串变为一整型类型的数字输出出来 若字符串内无数字则输出0 此处输出按十进制输出 字符串开头的空格会自动扫描为空 函数改编以及思路 对该函数
  • iframe无边框(隐藏边框)

    用css的border none来去掉iframe的边框在IE下起不了作用 将iframe的frameborder属性的值设为no就可以
  • Java--==与equals()的区别

    一 使用的对象 基本数据类型 equals 引用数据类型 二 比较内容 是否为同一地址 equals 未重写 是否为同一地址 已重写 引用数据类型内容 三 重写 public boolean equals Objeat obj if thi
  • Python接单一个月,副业居然比主业收入要多?

    python爬虫肯定是可以当副业的 我身边一个伙伴就靠会python爬虫这一项技能一个月差不多能有一万多收入 他截图给我看的他的收入图是这样的 人家一个月就靠接单这个副业都比很多人主业收入要多 每个月除主业外还有一万多收入 财务就相对自由的
  • 学习笔记二:IBIS模型编辑报错纠正

    新建IBIS文件后 写好了相应的IBIS模型文件 写好文件后 最好要检查下是否符合ibis语法 注意 第一点 IBIS头文件的 File name 此处名称需要和文件名称相同 同时名称字符数需在12个字符之内 否则会报错 File name
  • 一个javaer面试Python

    Python初面 一 初面缘由 今天是2022年的6月18日 广州 中雨转阴 非天气预报 我怀揣着紧张而有激动的心情趁着周末悄悄去面试了一次 说是去面试 其实也和玩差不多 公司的工作氛围很不错 空调很凉 零食很多 但是我没有心情享用 附上一
  • HFSS 3D LAOUT PCB 裁剪,差分线,过孔仿真和优化

    我本身不是做天线设计的 所以HFSS这个软件给我主要还是做PCB级别的高速信号完整性仿真 一般2 5D的仿真软件无法对过孔和跨平面进行仿真 所以要借助三维电磁软件进行 今天就针对PCB进行裁剪 为什么要裁剪 以为如果把整个PCB一起仿真的话
  • 移动APP专项测试

    什么是移动端测试 移动端测试是指对移动应用进行的测试 即实体的特性满足需求的特性 简言之就是针对移动平台的软件进行的测试 比如针对手机 ipad等平台上的各种app功能和性能展开的测试 相较于传统的web端的测试 移动端的测试受手机屏幕大小
  • 127.0.0.1和localhost的区别

    要比较两个东西有什么不同 首先要弄清两者的概念 所以 我们从概念开始 localhost 也叫local 正确的解释是 本地服务器 127 0 0 1 在windows等系统的正确解释是 本机地址 本机服务器 我们再看看他们的工作原理 lo
  • 关于块元素和行元素之间的转换

    如何让块元素变成行元素 将块级元素设置为行内元素 inline 可以通过以下几种方式 1 display inline 这个是最直接的方式 通过设置display样式为inline 可以将块级元素变为行内元素 例如 css div disp
  • element的日期组件-两个的和单个的组件

    dateOne vue
  • 云计算技术基础第1章 云的概念以及类型

    章节安排 第一章 云的概念及类型 第二章 虚拟化技术 第三章 云计算的架构和国内外研究现状 第四章 云计算与大数据 第五章 海量数据存储技术 第六章 云平台应用 本章内容 计算模式的回顾 云计算概念与特征 云计算的分类 云计算的发展动因 云
  • Spring Cloud Alibaba 大型微服务项目实战

    作者介绍 程序员十三 多年一线开发经验 历任高级开发工程师 后端主程 技术部门主管等职位 同时也是开源项目的爱好者和贡献者 掘金优秀作者 CSDN 博客专家 实体图书作者 专栏作者 视频讲师 小册介绍 Spring Cloud Alibab
  • 利用Python通过频谱分析和KNN完成iphone拨号的语音识别

    最近这段时间 学校里的事情实在太多了 从七月下旬一直到八月底实验室里基本天天十二点或者通宵 实在是没有精力和时间来写博客 这周老师出国开会 也算有了一个短暂的休息机会 刚好写点有意思的东西 上周在天津的会议上碰到一个北交的姐们儿 她想利用小