【问题标题】:ufunc 'multiply' did not contain a loop with signature matching types (dtype('<U32'), dtype('<U32')) -> dtype('<U32')ufunc 'multiply' 不包含签名匹配类型的循环 (dtype('<U32'), dtype('<U32')) -> dtype('<U32')
【发布时间】:2023-04-03 00:24:01
【问题描述】:

上下文

我正在尝试使用 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,并将返回异常值的索引和值。

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

注意:查看统计数据,数据可能存在严重问题

查找所有列中的异常值的代码(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

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

【问题讨论】:

    标签: python pandas data-science outliers iqr


    【解决方案1】:

    对于问题 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 列不是一个列,因此您将无法找到它的异常值。确保只迭代您实际要对其执行计算的列。

    【讨论】:

    • 谢谢。我不知道为什么以前的代码不起作用,但我敢打赌 np.percentile 遇到了问题。我做了一些有效的改变。
    • 我还确保我没有遍历日期和位置列。我将位置列变成了数字列。感谢您指出这一点。
    【解决方案2】:

    问题可能与 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
    

    第二步

    我将所有要删除异常值的列放入一个列表中。

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

    第三步

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-07-28
      • 2021-11-23
      • 2018-07-25
      • 1970-01-01
      • 2021-12-15
      • 2020-12-17
      • 1970-01-01
      • 1970-01-01
      • 2016-08-06
      相关资源
      最近更新 更多