安装
- 安装python和go的环境,
- 在debian和ubuntu系统上,还要
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中实现傅里叶变换,然后把结果绘图表示出来,需要安装对应的python库。
首先,需要依次安装numpy,scipy,matplotlib这三个库
为了在终端能够绘制显示出结果的图像,还需要安装两个软件:
- tk开发包: sudo apt-get install tk-dev
- Python的tk模块:sudo apt-get install python-tk
然后就可以测试了。
首先测试直接运行python代码能否成功fft并绘图:
编写好代码fft2.go(代码在最后),然后输入:
python fft2.go
成功绘图:
下面测试用go调用python的fft函数
需要改写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)
}