使用Python

时间:2015-07-15 22:19:59

标签: python numpy regression nonlinear-functions

我在混乱的中间继承了一个项目,更糟糕的是我只是在学习python。

我设法在我的代码和结果中实现了一个多项式函数 与本网页示例中发布的内容相同。 [z = numpy.polyfit(x,y,5)]

但是,我想知道如何修改程序,以便我可以插入一个y的已知值的输入来查找x。

换句话说。我有x和y数组,其中: - 数组x保存已知公斤重量的值(0.0,0.5,1.0,1.5,2.0) - 数组y(0.074581967,0.088474754,0.106797419,0.124461935,0.133726833)

我有一个程序,它读取一个重量和由phidget创建的张力,并生成该程序使用的数组。

我需要完成的是从phidget读取下一个值,并能够从提供的数组中将读数转换为千克。

有办法做到这一点吗?我觉得我只缺少一行代码,但我不知道如何从公式中实现返回值的结果。 (z)的

提前致谢。

根据要求添加的代码

from Phidgets.PhidgetException import PhidgetException
from Phidgets.Devices.Bridge import Bridge, BridgeGain

import datetime
import os
import re
import sys
import time
import numpy


wgh = list()
avg = list()
buf = list()
x = []
y = []


def nonlinear_regression():   # reads the calibration mapping and generates the conversion coefficients

    fd = open("calibration.csv", "r")

    for line in fd:
        [v0, v1] = line.split(",")
        x.append(float(v0))
        y.append(float(v1[:len(v1) - 1]))

    xdata = numpy.array(x)
    ydata = numpy.array(y)


    z = numpy.polyfit(x, y, 5)      

    return z       


def create_data_directory():   # create the data directory
    if not os.path.exists("data"):
        os.makedirs("data")

def parse_config():   # get config-file value
    v = int()

    config = open("config.properties", "r")
    for line in config:
        toks = re.split(r"[\n= ]+", line)
        if toks[0] == "record_interval":
            v = int(toks[1])

    return v

def read_bridge_data(event):   # read the data
    buf.append(event.value)

def record_data(f_name, date, rms):
    if not os.path.isfile(f_name):
        fd = open(f_name, "w")
        fd.write("time,weight\n")
        fd.write(datetime.datetime.strftime(date, "%H:%M"))
        fd.write(",")
        fd.write(str(rms) + "\n")
        fd.close()
    else:
        fd = open(f_name, "a")
        fd.write(datetime.datetime.strftime(date, "%H:%M"))
        fd.write(",")
        fd.write(str(rms) + "\n")
        fd.close()
    print("Data recorded.")

def release_bridge(event):   # release the phidget device
    try:
        event.device.closePhidget()
    except:
        print("Phidget bridge could not be released properly.")
        sys.exit(1)


def main():

    create_data_directory()

    RECORD_INTERVAL = parse_config()        # get the config-file value
    calibrate = nonlinear_regression()      # get calibration function; use like: calibrate(some_input)
    bridge = Bridge()

    try:
        bridge.setOnBridgeDataHandler(read_bridge_data)
        bridge.setOnDetachHandler(release_bridge)   # when the phidget gets physically detached
        bridge.setOnErrorhandler(release_bridge)   # asynchronous exception (i.e. keyboard interrupt)
    except:
        print("Phidget bridge event binding failed.")
        sys.exit(1)

    try:
        bridge.openPhidget()
        bridge.waitForAttach(3000)
    except:
        print("Phidget bridge opening failed.")
        sys.exit(1)

    last_record = int()
    while (True):
        date = datetime.datetime.now()
        f_name = "data\\" + datetime.datetime.strftime(date, "%B_%d_%Y") + ".csv"

        curr = time.time() * 1000
        if (curr - last_record) > (RECORD_INTERVAL * 1000):
            try:
                bridge.setDataRate(10)
                last = time.time() * 1000
                bridge.setEnabled(0, True)
                while (time.time() * 1000 - last) < 1000:   # collects over 1 sec
                    pass
                bridge.setEnabled(0, False)
            except:
                print("Phidget bridge data reading error.")
                bridge.setEnabled(0, False)
                bridge.closePhidget()
                sys.exit(1)
            vol = sum(buf) / len(buf)

            del buf[:]
            last_record = curr

            record_data(f_name, date, vol)   # replace curr with calibrated data

        #THIS IS WHERE I WILL LIKE TO INCORPORATE THE CHANGES TO SAVE THE WEIGHT                
            #record_data(f_name, date,  conversion[0] * vol + conversion[1])   # using the linear conversion function
        else:
            time.sleep(RECORD_INTERVAL - 1)   # to reduce the CPU's busy-waiting

if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:0)

来自校准的线性转换函数由numpy.polyfit作为系数数组返回。由于你为polyfit的度数参数传递了5,你将得到一个包含六个系数的数组:

f(x)= ax 5 + bx 4 + cx 3 + dx 2 + ex + ˚F

其中a,b,c,d,e和f是z返回的nonlinear_regression数组的元素。

要实施线性转化公式,只需使用幂算子**z的元素和vol的值:

vol_calibrated = vol**5 * z[0] + vol**4 * z[1] + vol**3 * z[2] + vol**2 * z[3] + vol * z[4] + z[5]

或更一般地说:

degree = len(z) - 1
vol_calibrated = sum(vol**(degree-i) * coeff for i, coeff in enumerate(z))