意外的 dtype 转换导致不可转换的数组

Unintended dtype conversion leads to uncastable array

我的一个 class 方法似乎将数据类型从 float64 转换为字符串。

    def transfer(self, sample):
        """Takes a list, tupel or arry as input."""
        c = self.bias + np.dot(sample[:-1], self.weights)
        return c

如果使用以下输入手动调用此函数:

sample = learning_data.loc[0, "1":"3"]
1   -0.383362
2   -0.487992
3    0.000000
Name: 0, dtype: float64
x.transfer(sample)

我得到了正确的结果。但是如果函数被调用自:

    def learn(self, vector):
    for sample in vector:
        y = self.activator(self.transfer(sample))

        if y != sample[-1]:
            w = self.update_weigts(y, sample)
            b = self.update_bias(y, sample)

        else:
            pass

有:

vector = learing_data.loc[: ,"1":"3"]
     0       1          2       3
565  1  -0.761398   -1.060793   0
670  1  1.861826    1.822200    0
72   1  1.440886    1.718266    0
898  1  -2.472685   -1.699168   0
1773 1  1.075351    4.293892    1

我收到以下错误:

--> y = self.activator(self.transfer(sample))
TypeError: Cannot cast array data from dtype('float64') to dtype('<U32') 
according to the rule 'safe'

我先查查查了什么'

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1400 entries, 565 to 1515
Data columns (total 4 columns):
0    1400 non-null int64
1    1400 non-null float64
2    1400 non-null float64
3    1400 non-null int64
dtypes: float64(2), int64(2)
memory usage: 94.7 KB

里面没有 stirng 类型,函数 get 是这样调用的:

x.learn(learning_data.loc[:, '1':'3'])

所以没有对传输函数的数据类型的适当操作。对数据所做的唯一事情是学习函数中的 for 循环。

我错过了什么?

重现错误的最少代码:

import numpy as np
import pandas as pd
import random

class Perzeptron(object):
    def __init__(self, n):
        """n is the number of weights that are needed."""
        self.weights = np.array([random.uniform(-1, 1) for f in range(n)])
        self.bias =  random.uniform(-1, 1)
        self.rate = 1


    def transfer(self, sample):
        c = self.bias + np.dot(sample[:-1], self.weights)
        return c


    def activator(self, c):
        if c > 0:
            return 1
        else:
            return 0


    def learn(self, vector):
        for sample in vector:
            y = self.activator(self.transfer(sample))

            if y != sample[-1]:
                w = 1  # call to jet another function
                b = 2  # call to jet another function

            else:
                pass

v = {'0': {565: 1, 670: 1, 72: 1, 898: 1, 1773: 1},
'1': {565: -0.761397898, 670: 1.8618260619999998, 72: 1.4408856630000002,
 898: -2.472684622, 1773: 1.0753508809999999},
'2': {565: -1.060793281, 670: 1.8221998209999999, 72: 1.7182657719999999,
 898: -1.699168086, 1773: 4.293891907},
'3': {565: 0, 670: 0, 72: 0, 898: 0, 1773: 1}}

learning_data = pd.Dataframe(v)
x = Perzeptron(2)
x.learn(learning_data.loc[:, '1':'3'])

编辑:

问题是 sample 没有我预期的形状。删除 Dataframe 的第 0 列并使用

x.learn(learning_data.values)

给出了我正在寻找的结果。

嗯,关于您的样本是否应该是 table 中的每一行还不是很清楚,但现在它只是遍历列而不是任何实际数字。所以我能够通过这样做使代码工作。修复位于 learn() 函数内的 for 循环内:

import numpy as np
import pandas as pd


class Perzeptron(object):
    def __init__(self, n):
        """n is the number of weights that are needed."""
        self.weights = np.array([np.random.uniform(-1, 1) for f in range(n)])
        self.bias = np.random.uniform(-1, 1)
        self.rate = 1

    def transfer(self, sample):
        c = self.bias + np.dot(sample[:-1], self.weights)
        return c

    def activator(self, c):
        if c > 0:
            return 1
        else:
            return 0

    def learn(self, vector):
        for _, sample in vector.iterrows():
            y = self.activator(self.transfer(sample))

            if y != sample[-1]:
                w = 1  # call to jet another function
                b = 2  # call to jet another function

            else:
                pass


v = {'0': {565: 1, 670: 1, 72: 1, 898: 1, 1773: 1},
     '1': {565: -0.761397898, 670: 1.8618260619999998, 72: 1.4408856630000002,
           898: -2.472684622, 1773: 1.0753508809999999},
     '2': {565: -1.060793281, 670: 1.8221998209999999, 72: 1.7182657719999999,
           898: -1.699168086, 1773: 4.293891907},
     '3': {565: 0, 670: 0, 72: 0, 898: 0, 1773: 1}}

learning_data = pd.DataFrame(v)
print(learning_data)
x = Perzeptron(2)
x.learn(learning_data.loc[:, '1':'3'])