ufunc 'multiply' 不包含带有签名匹配类型的循环 (dtype('<U32'), dtype('<U32')) -> dtype('<U32')

ufunc 'multiply' did not contain a loop with signature matching types (dtype('<U32'), dtype('<U32')) -> dtype('<U32')

上下文

我正在尝试使用 python 在数据框的所有列中查找异常值。

步骤:

  1. 创建了一个通过 IQR 查找异常值的函数
  2. 在一列上测试了函数。
  3. 使用 for 循环在所有列上实现了函数。

我的等级

我对机器学习和数据科学完全陌生。我只知道 python 和 pandas,所以我目前正在扩展我在机器学习方面的知识。关于机器学习算法可以处理哪些数据类型以及为什么缺失值是个问题等,我不知道很多理论

数据概览

<class 'pandas.core.frame.DataFrame'>
Int64Index: 2768 entries, 14421 to 98025
Data columns (total 10 columns):
 #   Column                 Non-Null Count  Dtype         
---  ------                 --------------  -----         
 0   date                   2768 non-null   datetime64[ns]
 1   location               2768 non-null   object        
 2   new_deaths             2768 non-null   float64       
 3   female_smokers         2768 non-null   float64       
 4   male_smokers           2768 non-null   float64       
 5   population             2768 non-null   float64       
 6   people_vaccinated      2768 non-null   float64       
 7   cardiovasc_death_rate  2768 non-null   float64       
 8   aged_65_older          2768 non-null   float64       
 9   gdp_per_capita         2768 non-null   float64     
..... #The rest are indicator columns with dummy values that were categorical columns before.  
dtypes: datetime64[ns](1), float64(8), object(1)

在一列中查找离群值的代码

我创建了一个函数来查找 IQR 并将 return 异常值的索引和值。

def find_outliers_tukey(x):
  q1 = np.percentile(x, 25)
  q3 = np.percentile(x, 75)

  iqr = q3-q1
  floor = q1 -1.5*iqr
  ceiling = q3 +1.5*iqr

  outlier_indices = list(x.index[ (x < floor)|(x > ceiling) ])
  outlier_values = list(x[outlier_indices])

  return outlier_indices, outlier_values

当我调用函数时:

tukey_indices, tukey_values = find_outliers_tukey(df.new_deaths)
print(f"Outliers in new deatths are {np.sort(tukey_values)}")

输出:

Outliers in new deatths are []

问题 1

为什么这没有给我异常值?往下看

# Statistics of the new deaths column

Mean = 145.745266
std = 796.284067    
min = -1918.000000
25% = 0.000000
50% = 2.000000
75% = 18.000000
max = 18000.000000

Note: Looking at the stats, there's probably something seriously wrong with the data

在所有列中查找异常值的代码(for 循环)

for feature in df.columns:
  tukey_indices, tukey_values = find_outliers_tukey(feature)
  print(f"Outliers in {feature} are {tukey_values} \n")

输出:

UFuncTypeError                            Traceback (most recent call last)
<ipython-input-16-b01dad9e55a2> in <module>()
      1 for feature in df.columns:
----> 2   tukey_indices, tukey_values = find_outliers_tukey(feature)
      3   print(f"Outliers in {feature} are {tukey_values} \n")

4 frames
<__array_function__ internals> in percentile(*args, **kwargs)

/usr/local/lib/python3.7/dist-packages/numpy/lib/function_base.py in _quantile_ureduce_func(a, q, axis, out, overwrite_input, interpolation, keepdims)
   3965             n = np.isnan(ap[-1:, ...])
   3966 
-> 3967         x1 = take(ap, indices_below, axis=axis) * weights_below
   3968         x2 = take(ap, indices_above, axis=axis) * weights_above
   3969 

UFuncTypeError: ufunc 'multiply' did not contain a loop with signature matching types (dtype('<U32'), dtype('<U32')) -> dtype('<U32')

问题 2

这个错误是什么意思/我为什么会收到这个?

对于问题 1,您的代码在我这边似乎工作正常,但我当然没有您的原始数据。

对于问题2,有两个问题。首先是您将列 names 传递给 find_outliers_tukey 而不是列本身。使用 iteritems 迭代 (column name, column Series):

for feature, column in df.iteritems():
    tukey_indices, tukey_values = find_outliers_tukey(column)
    print(f"Outliers in {feature} are {tukey_values} \n")

第二个问题,您将在解决第一个问题后 运行 进入,是您的 location 列不是一个列,因此您将无法找到离群值为了它。确保只迭代您实际要对其执行计算的列。

问题可能出在 numpy 函数 'percentile' 以及我如何将参数传递给 find_outliers_tukey 函数。所以这些改变对我有用

步骤 1

  1. 包括两个参数;一个是 df 的名称,另一个是特征的名称。
  2. 明确地将特征参数放入 df。
  3. 访问特征时不要使用属性链,使用分位数而不是百分位数。
def find_outliers_tukey(df:"dataframe", feature:"series") -> "list, list":
  "write later"

  q1 = df[feature].quantile(0.25)
  q3 = df[feature].quantile(0.75)

  iqr = q3-q1
  floor = q1 -1.5*iqr
  ceiling = q3 +1.5*iqr

  outlier_indices = list(df.index[ (df[feature] < floor) | (df[feature] > ceiling) ])
  #outlier_values = list(df[feature][outlier_indices]) 

  #print(f"outliers are {outlier_values} at indices {outlier_indices}")
  #return outlier_indices, outlier_values
  return outlier_indices

第 2 步

我将所有要从中删除离群值的列放入列表中。

df_columns = list(df.columns[1:56])

第 3 步

这里没有变化。 find_outliers_tukey 函数只使用了 2 个参数而不是 1 个参数。哦,我存储了异常值的索引以备将来使用。

index_list = []

for feature in df_columns: 
  index_list.extend(find_outliers_tukey(df, feature))

这为我提供了更好的列统计结果。