sudo apt install python-all-dev
sudo apt-get install pkg-config
go get github.com/sbinet/go-python
根据这个教程测试了以下,发现可以得到相同的结果(根据教程我写的文件放在后面test.go)
https://www.jianshu.com/p/a49047a474e5
注意一点,就是导入当前目录,教程使用的是空字符串""
, 我测试以后发现不行,就使用了绝对路径"/home/zhang/桌面/go-python"
,如果不导入python文件所在目录,是找不到python文件的。
如果这个教程里面的全部能测试成功,那么go调用python基本没有问题了
想要在python中实现傅里叶变换,然后把结果绘图表示出来,需要安装对应的python库。
首先,需要依次安装numpy,scipy,matplotlib这三个库
为了在终端能够绘制显示出结果的图像,还需要安装两个软件:
然后就可以测试了。
编写好代码fft2.go(代码在最后),然后输入:
python fft2.go
成功绘图:
需要改写fft2.py,改写后的代码放在最后(fft.py)。编写main.go,在其中导入fft.py所在目录,然后就可以调用fft.py了(main.go放在最后)
运行,可以输出结果:
下面是关于go-python这个包的使用笔记
go导包:m= python.PyImport_ImportModule("fib")
有了包以后就可以调用里面的函数,访问变量
访问变量: path:= m.GetAttrString("path")
//访问b包中名叫path的变量,事实上返回的是一个python-list
获取python-list中的一个元素 item := python.PyList_GET_ITEM(path,i)
//返回一个python-string
python-string转为string s:=python.PyString_AsString(item)
访问函数:fib:= m.GetAttrString("fib")
//根据函数名,返回python-function
调用函数: out:=fib.CallFunction(python.PyInt_FromLong(10))
//返回python-int
pyint转为int:python.PyInt_AsLong(out)
test.go
package main import ( "fmt" "github.com/sbinet/go-python" "os" ) func init(){ err:= python.Initialize() if err!=nil{ panic(err.Error()) } } func main1(){ rc := python.Py_Main(os.Args) os.Exit(rc) //go run main.go --version //2.7.17 } func main2(){ m:= python.PyImport_ImportModule("sys") if m == nil{ fmt.Println("import error") } path:= m.GetAttrString("path") if path ==nil{ fmt.Println("get path error") return } size := python.PyList_GET_SIZE(path) for i:=0;i<size;i++{ item := python.PyList_GET_ITEM(path,i) s:=python.PyString_AsString(item) fmt.Println(s) } //打印path ///usr/lib/python2.7 ///usr/lib/python2.7/plat-x86_64-linux-gnu ///usr/lib/python2.7/lib-tk ///usr/lib/python2.7/lib-old ///usr/lib/python2.7/lib-dynload ///home/zhang/.local/lib/python2.7/site-packages ///usr/local/lib/python2.7/dist-packages ///usr/lib/python2.7/dist-packages } func main(){ m:= python.PyImport_ImportModule("sys") if m == nil{ fmt.Println("import error") } path:= m.GetAttrString("path") if path ==nil{ fmt.Println("get path error") return } //python文件存放的路径 curdir:=python.PyString_FromString("/home/zhang/桌面/go-python/set_path") err:=python.PyList_Insert(path,0,curdir) if err!=nil{ print(err) } size := python.PyList_GET_SIZE(path) for i:=0;i<size;i++{ item := python.PyList_GET_ITEM(path,i) s:=python.PyString_AsString(item) fmt.Println(s) } m= python.PyImport_ImportModule("fib") if m == nil{ fmt.Println("import fib error") return } size = python.PyList_GET_SIZE(path) for i:=0;i<size;i++{ item := python.PyList_GET_ITEM(path,i) s:=python.PyString_AsString(item) fmt.Println(s) } fib:= m.GetAttrString("fib") if fib ==nil{ fmt.Println("get fib error") return } out:=fib.CallFunction(python.PyInt_FromLong(10)) if out==nil{ fmt.Println("call fib error") return } fmt.Printf("fib(%d) = %d\n",10,python.PyInt_AsLong(out)) }
fft2.py
# _*_ coding: utf-8 _*_ import numpy as np from scipy.fftpack import fft,ifft import matplotlib.pyplot as plt #采样点选择1400个,因为设置的信号频率分量最高为600赫兹,根据采样定理知采样频率要大于信号频率2倍,所以这里设置采样频率为1400赫兹(即一秒内有1400个采样点,一样意思的) def fft_func(): x=np.linspace(0,1,1400) #设置需要采样的信号,频率分量有180,390和600 y=7*np.sin(2*np.pi*180*x) + 2.8*np.sin(2*np.pi*390*x)+5.1*np.sin(2*np.pi*600*x) yy=fft(y) #快速傅里叶变换 yreal = yy.real # 获取实数部分 yimag = yy.imag # 获取虚数部分 yf=abs(fft(y)) # 取绝对值 yf1=abs(fft(y))/len(x) #归一化处理 yf2 = yf1[range(int(len(x)/2))] #由于对称性,只取一半区间 xf = np.arange(len(y)) # 频率 xf1 = xf xf2 = xf[range(int(len(x)/2))] #取一半区间 plt.subplot(221) plt.plot(x[0:50],y[0:50]) plt.title('Original wave') plt.subplot(222) plt.plot(xf,yf,'r') plt.title('FFT of Mixed wave(two sides frequency range)',fontsize=7,color='#7A378B') #注意这里的颜色可以查询颜色代码表 plt.subplot(223) plt.plot(xf1,yf1,'g') plt.title('FFT of Mixed wave(normalization)',fontsize=9,color='r') plt.subplot(224) plt.plot(xf2,yf2,'b') plt.title('FFT of Mixed wave)',fontsize=10,color='#F08080') plt.show() fft_func()
fft.py:
# _*_ coding: utf-8 _*_ import numpy as np from scipy.fftpack import fft,ifft import matplotlib.pyplot as plt import json def fft_func(data): z=json.loads(data) y=np.array(z) yf1=abs(fft(y))/len(z) #归一化处理 yf2 = yf1[range(int(len(z)/2))] #由于对称性,只取一半区间 yA = yf2.tolist() return str(yA)# 返回float的 list
main.go
package main import ( "encoding/json" "fmt" "github.com/sbinet/go-python" ) func init(){ err:= python.Initialize() if err!=nil{ panic(err.Error()) } } func main(){ m:= python.PyImport_ImportModule("sys") if m == nil{ fmt.Println("import error") } path:= m.GetAttrString("path") if path ==nil{ fmt.Println("get path error") return } //python文件存放的路径 curdir:=python.PyString_FromString("/home/zhang/桌面/go-python/fft") python.PyList_Insert(path,0,curdir) //和获取包 m=python.PyImport_ImportModule("fft") if m ==nil{ fmt.Println("import err") } fft_func := m.GetAttrString("fft_func") if fft_func==nil{ fmt.Println("get fft_func error") return } raw:=[]int{1,1,1,1,1,1,1,1} //raw:=[]float64{1.0,1.0,2.3} //raw :=make(map[string][]int) //raw["data"]=[]int{1,2,3} byt,_:=json.Marshal(raw) str := string(byt) res := fft_func.CallFunction(python.PyString_FromString(str)) if res ==nil{ fmt.Println("call fft_func error") return } s:=python.PyString_AS_STRING(res) print(s) }