【问题标题】:What are the best first steps when diagnosing AttributeError: 'str' object has no attribute 'str' error诊断 AttributeError 时最好的第一步是什么:“str”对象没有属性“str”错误
【发布时间】:2020-09-28 22:26:29
【问题描述】:

首先,我使用 pandas 函数 pd.read_sql() 创建一个数据集。据我所知,所有导入的列都是字符串。

然后我创建一个新的空变量并定义一个函数,就像这样(tinyurl.com/tnr9b83):

df['status_update'] = ""
def f(row):
    if (row['priority'] in ("1","2")) and (row['failed'] == "Y"):
        val = "F"
    elif (row['priority'] in ("1","2")):
        val = row['status'].str.slice(0,1)
    else:
        val = "X"
    return val

然后我尝试更改数据集的每一行,以便:

  • 如果一条记录在 ("1","2") 中具有优先级并且失败 = "Y",它将获得 status_update = "F"
  • 否则,如果记录在 ("1","2") 中具有优先级,它将获得 status_update = 列“状态”的第一个字母子字符串
  • 否则它会得到 status_update = "X"

所以我跑了:

df['status_update'] = df.apply(f, axis=1)

..但这给出了:

AttributeError: 'str' object has no attribute 'str'

我尝试了替代语法但无济于事。其他报告此错误的人似乎有不同的情况和解决方案。作为一个新的 Python 程序员,了解为什么这种语法/逻辑在这种情况下不起作用的最佳第一步/工具/功能是什么?

编辑:澄清:错误与“val = row['status'].str.slice(0,1)”有关 Edit2:值得注意的是,当我打开数据查看器时,它有类似 []...[]...[] 的东西,而不是新的“status_update”字段中许多观察的单个字符值,所以我猜返回某种数组或向量,而不是单个子字符串。

【问题讨论】:

  • 什么是row?它是数据框行对象,还是普通字典?尝试将print(type(row)) 放在函数顶部。
  • 'row' 是数据框行对象的占位符,我相信。我添加了您的建议,但没有看到要分享的相关输出。该脚本的目的是根据提供的条件更改所有行的“status_update”列的值。语法从这里的最佳答案中提取:tinyurl.com/tnr9b83
  • 错误提示row['status'] 已经是str。什么样的对象有str 属性?在 Python 中,每类对象都有记录的属性和方法。如果你的类错了,或者属性错了,你就会得到这种错误。这不是语法问题。您需要将对象与其正确的属性相匹配。
  • 谢谢,hpaulj。我不确定这是否是一个反问,但我猜 str 对象具有 str 属性,所以,正如你所说, row['status'] 已经是一个 str。但如果这是真的,为什么不将其更改为 row['status'].slice(0,1) 工作,正如 Gels_YT 建议的那样?

标签: python pandas numpy


【解决方案1】:
val = row['status'].str.slice(0,1)

尝试删除此代码中的 .str 努力去做吧

val = row['status'].slice(0,1)

我不知道你的行是什么,但我猜它是一个字符串

【讨论】:

  • 我尝试过的众多解决方案之一。这将返回“AttributeError:‘str’对象没有属性‘slice’”。不过,这是否意味着 python 正在处理“str”对象?正如我们俩所期望的那样?当我运行df[status_update].dtypes I get dtype('O')`时,根据这个答案,这似乎是一个python str:stackoverflow.com/questions/37561991/what-is-dtypeo-in-pandas
  • sliceSeries.str 集合中的一个额外方法。它不是 Python str 方法。大概它的行为类似于切片索引:astring[0:1]
【解决方案2】:

让我们用字符串元素定义一个简单的数据框。你真的应该提供这样一个例子。它使调试和建议修复变得更加容易。我可能对您的框架的基本特征有误。无论如何:

In [273]: df1 = pd.DataFrame([['abc'],['bcd']], columns=['a'])                                
In [274]: df1                                                                                 
Out[274]: 
     a
0  abc
1  bcd

系列:

In [275]: df1['a']                                                                            
Out[275]: 
0    abc
1    bcd
Name: a, dtype: object
In [276]: type(df1['a'])                                                                      
Out[276]: pandas.core.series.Series

它有一个str 属性,可以访问一些字符串方法:

In [277]: df1['a'].str                                                                        
Out[277]: <pandas.core.strings.StringMethods at 0x7febb75c4ba8>
In [278]: df1['a'].str.upper()                                                                
Out[278]: 
0    ABC
1    BCD
Name: a, dtype: object
In [279]: df1['a'].str.slice(0,1)                                                             
Out[279]: 
0    a
1    b
Name: a, dtype: object

现在定义一个可以像你一样“应用”的函数。首先清楚地了解该函数必须使用哪些对象。没猜错!

In [280]: def foo(row): 
     ...:     print(type(row), type(row['a'])) 
     ...:     return row 
     ...:                                                                                     
In [281]: df1.apply(foo, axis=1)                                                              
<class 'pandas.core.series.Series'> <class 'str'>
<class 'pandas.core.series.Series'> <class 'str'>
<class 'pandas.core.series.Series'> <class 'str'>
Out[281]: 
     a
0  abc
1  bcd

所以row['a'] 是一个字符串,而不是一个系列。如错误所示,str 对象本身没有str 属性。它确实有像upper 这样的方法。要对其进行切片,我们必须使用索引符号,而不是 slice 方法。

In [284]: def foo(row): 
     ...:     print(type(row), type(row['a'])) 
     ...:     return row['a'][0:1] 
     ...:                                                                                     
In [285]: df1.apply(foo, axis=1)                                                              
<class 'pandas.core.series.Series'> <class 'str'>
<class 'pandas.core.series.Series'> <class 'str'>
Out[285]: 
0    a
1    b
dtype: object

或将str.slice 应用于row 系列对象:

In [288]: def foo(row): 
     ...:     return row.str.slice(0,1) 
     ...:      
     ...:                                                                                     
In [289]: df1.apply(foo, axis=1)                                                              
Out[289]: 
   a
0  a
1  b

当您收到属性错误时,请检查对象的类及其文档。一种或另一种方式是对象的类与您尝试使用的属性/方法不匹配。有时是因为您误读了文档(或者一开始就没有阅读它们),但更多时候是因为对象不属于您认为应该属于的类。

===

检查slice 属性/方法:

In [297]: df1.slice                                                                           
....
AttributeError: 'DataFrame' object has no attribute 'slice'

In [298]: df1['a'].slice                                                                      
....
AttributeError: 'Series' object has no attribute 'slice'

In [299]: df1['a'].str.slice                                                                  
Out[299]: <bound method StringMethods.slice of <pandas.core.strings.StringMethods object at 0x7febb75c4ba8>>

In [300]: 'astring'.slice                                                                     
...
AttributeError: 'str' object has no attribute 'slice'

【讨论】:

  • 非常感谢,hpaulj;这很有意义,并帮助我了解如何在未来处理这些类型的错误!
猜你喜欢
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多