Python pandas,使用 .str.contains 搜索数据框列的子字符串时出错

Posted

技术标签:

【中文标题】Python pandas,使用 .str.contains 搜索数据框列的子字符串时出错【英文标题】:Python pandas, errors using .str.contains to search dataframe column for substring 【发布时间】:2018-06-12 13:53:15 【问题描述】:

如果您使用 python 2.7、pandas 0.22 和 easygui 0.98.1 在此问题上提供任何帮助,我将不胜感激。

我正在尝试将 csv 加载到 pandas 中,使用 easygui 从用户选择的列表中分配列名(我认为返回为字符串列表)并在数据框的特定列中搜索子字符串。

import easygui as eg
import pandas as pd

# define vars_vars from choices of imagej outputs
vars_vars = eg.multchoicebox
            (msg="\n\n\n\nPlease highlight variables included in ImageJ analysis:",
             title="IF Analysis - 2017",
             choices=["integrated density", "mean", 
                      "mean grey value", "area fraction"])

# add required imagej columns for later processing
vars_vars.insert(0, "label")
vars_vars.insert(0, "#")

#User input for csv file
file = eg.fileopenbox()

# load into dataframe using pandas and assign columns using chosen variables
df = pd.read_csv(file, header=None, names=None)
df.columns = vars_vars

# Search 'label' column for certain substring
df[df['label'].str.contains('substring')]

但是我收到了这个错误:

Traceback (most recent call last):
  File "C:/Users/User/.PyCharmCE2017.3/config/scratches/scratch.py", line 61, in <module>
    df[df['label'].str.contains('nsv')]
  File "C:\Users\User\Miniconda2\envs\test2\lib\site-packages\pandas\core\generic.py", line 3614, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'str'

我尝试用谷歌搜索它,并找到了这些修复

df['label'] = df['label'].map(str)
df['label'] = df['label'].astype(str)
df['label'] = df['label'].astype(baseline)

以及我称之为整个数据框而不是 df['label'] 的那些变体。

但是,这些都不会导致通过该修复行后出现错误,但是当我执行 .str.contains 行时总是返回与以前类似的错误,该行指出数据框对象没有属性映射(对于 .map(str) ) 或 str (对于 .astype(x)) 行。


print type(df['label'])
print df.dtypes
print df['label'].head()
print (df['label'].info())
print type(df['label'][0])

返回

<class 'pandas.core.frame.DataFrame'>

#                      int64
label                 object
integrated density     int64
dtype: object

                                        label
0         nc4_al1_I+pP_4x_contra_ctx_blue.tif
1        nc4_al1_I+pP_4x_contra_ctx_green.tif
2         nc4_al1_I1+pP_4x_contra_ctx_red.tif
3          nc4_al1_I+pP_4x_contra_hc_blue.tif
4         nc4_al1_I+pP_4x_contra_hc_green.tif

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 695 entries, 0 to 694
Data columns (total 1 columns):
(label,)    695 non-null object
dtypes: object(1)
memory usage: 5.5+ KB
None

Traceback (most recent call last):
  File "C:/Users/Shon/.PyCharmCE2017.3/config/scratches/scratch.py", line 67, in <module>
    print type(df['label'][0])
  File "C:\Users\User\Miniconda2\envs\test2\lib\site-packages\pandas\core\frame.py", line 2137, in __getitem__
    return self._getitem_multilevel(key)
  File "C:\Users\User\Miniconda2\envs\test2\lib\site-packages\pandas\core\frame.py", line 2181, in _getitem_multilevel
    loc = self.columns.get_loc(key)
  File "C:\Users\User\Miniconda2\envs\test2\lib\site-packages\pandas\core\indexes\multi.py", line 2072, in get_loc
    loc = self._get_level_indexer(key, level=0)
  File "C:\Users\User\Miniconda2\envs\test2\lib\site-packages\pandas\core\indexes\multi.py", line 2362, in _get_level_indexer
    loc = level_index.get_loc(key)
  File "C:\Users\User\Miniconda2\envs\test2\lib\site-packages\pandas\core\indexes\base.py", line 2527, in get_loc
    return self._engine.get_loc(self._maybe_cast_indexer(key))
  File "pandas/_libs/index.pyx", line 117, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/index.pyx", line 139, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/hashtable_class_helper.pxi", line 1265, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas/_libs/hashtable_class_helper.pxi", line 1273, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 0

如果你们能提供任何帮助,我将不胜感激。


更新:

原来问题在于有一个多索引数据框。

df.columns.map(''.join).str.strip()

导致在打印其类型时将列更改为系列,这使我能够正确地 .str.contains 数据。

【问题讨论】:

type(df['label']) 返回什么? '' -- 感谢您的帮助 编辑:我做了 df.dtypes 并得到以下输出:# int64 label object integrated density int64 dtype: object 是的,没错,您的 df['label'] 不是系列,.str 访问器适用于系列。 df['label'].head() 返回的内容包括您的问题中的结果。谢谢。 已更新。谢谢你。您是否建议我尝试将列转换为系列? 另外,print(df['labels'].info())。你有一个结构奇怪的数据框。我试图真正了解您到底拥有什么。通常,type(df['label']) 返回 pd.Series。但你的没有。所以,你有一些非标准的东西。 【参考方案1】:

查看type(df['label']).info()的输出:

<class 'pandas.core.frame.DataFrame'> 
RangeIndex: 695 entries, 0 to 694 
Data columns (total 1 columns): 
(label,) 695 non-null object 
dtypes: object(1) memory usage: 5.5+ KB None

这个数据框中的列看起来好像是一个带有空元素的元组,这表示第二级为空的多索引列标题。

我建议我们首先尝试修复pd.read_cv 阻止创建多索引。但是,使用:

df.columns = df.columns.map(''.join).str.strip()

将多索引列标题展平为单级列索引,并为 df['label'] 创建 pd.Series 数据类型,然后允许使用字符串访问器和 contains

【讨论】:

@SK 如果此解决方案对您有所帮助,请通过检查此答案来介意accepting。谢谢。

以上是关于Python pandas,使用 .str.contains 搜索数据框列的子字符串时出错的主要内容,如果未能解决你的问题,请参考以下文章

python--pandas切片

python pandas使用经验

python之pandas简单介绍及使用

python 使用pandas #pandas导入csv

使用C#循环反复多次连接SQL数据库,出现“内部连接致命错误”的问题,怎么解决?

python之pandas简单介绍及使用