Python:检查dataframe列是否包含字符串类型

s90*_*00n 7 python dataframe

我想检查数据框中的列是否由字符串组成,因此我可以用数字标记它们以用于机器学习目的.有些列由数字组成,我不想更改它们.列示例如下所示:

TRAIN FEATURES
  Age              Level  
  32.0              Silver      
  61.0              Silver  
  66.0              Silver      
  36.0              Gold      
  20.0              Silver     
  29.0              Silver     
  46.0              Silver  
  27.0              Silver      
Run Code Online (Sandbox Code Playgroud)

谢谢=)

vc *_* 74 24

自这个问题提出四年以来,我相信仍然没有明确的答案。

我不认为字符串在 Pandas 中被视为一等公民(甚至 >= 1.0.0)。举个例子:

import pandas as pd
import datetime

df = pd.DataFrame({
    'str': ['a', 'b', 'c', None],
    'hete': [1, 2.0, datetime.datetime.utcnow(), None]
})

string_series = df['str']
print(string_series.dtype)
print(pd.api.types.is_string_dtype(string_series.dtype))

heterogenous_series = df['hete']
print(heterogenous_series.dtype)
print(pd.api.types.is_string_dtype(heterogenous_series.dtype))
Run Code Online (Sandbox Code Playgroud)

印刷

object
True
object
True
Run Code Online (Sandbox Code Playgroud)

因此,虽然hete不包含任何显式字符串,但它被视为字符串系列。

阅读文档后,我认为确保系列仅包含字符串的唯一方法是:

def is_string_series(s : pd.Series):
    if isinstance(s.dtype, pd.StringDtype):
        # The series was explicitly created as a string series (Pandas>=1.0.0)
        return True
    elif s.dtype == 'object':
        # Object series, check each value
        return all((v is None) or isinstance(v, str) for v in s)
    else:
        return False


print(is_string_series(string_series))
print(is_string_series(heterogenous_series))
Run Code Online (Sandbox Code Playgroud)

印刷

True
False
Run Code Online (Sandbox Code Playgroud)

2023 年 4 月更新

最近发布的 Pandas 2似乎也有同样的行为(上面的测试脚本与 Python 3.11 产生相同的输出)。


tot*_*ico 9

请注意,上述答案将包括 DateTime、TimeStamp、Category和其他数据类型。

使用object更具限制性(尽管我不确定其他人dtypes是否也会使用objectdtype):

  1. 创建数据框:

    df = pd.DataFrame({
        'a': ['a','b','c','d'], 
        'b': [1, 'b', 'c', 2], 
        'c': [np.nan, 2, 3, 4], 
        'd': ['A', 'B', 'B', 'A'], 
        'e': pd.to_datetime('today')})
    df['d'] = df['d'].astype('category')
    
    Run Code Online (Sandbox Code Playgroud)

看起来像这样:

   a  b    c  d          e
0  a  1  NaN  A 2018-05-17
1  b  b  2.0  B 2018-05-17
2  c  c  3.0  B 2018-05-17
3  d  2  4.0  A 2018-05-17
Run Code Online (Sandbox Code Playgroud)
  1. 您可以检查调用的类型dtypes

    df.dtypes
    
    a            object
    b            object
    c           float64
    d          category
    e    datetime64[ns]
    dtype: object
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您可以使用该items()方法列出字符串列并按以下方式过滤object

    > [ col  for col, dt in df.dtypes.items() if dt == object]
    ['a', 'b']
    
    Run Code Online (Sandbox Code Playgroud)
  3. 或者您可以使用 select_dtypes 显示仅包含字符串的数据框:

    df.select_dtypes(include=[object])
       a  b
    0  a  1
    1  b  b
    2  c  c
    3  d  2
    
    Run Code Online (Sandbox Code Playgroud)

  • 这是执行步骤 3 的更简洁(并且可能更快)的方法:`df.columns[df.dtypes=='object']` (2认同)

Scr*_*urr 8

是的,它可能.你用dtype

import pandas as pd
import numpy as np

df = pd.DataFrame({'a': ['a','b','c','d']})
if df['a'].dtype != np.number:
    print('yes')
else:
    print('no')
Run Code Online (Sandbox Code Playgroud)

您也可以使用dtype选择列 select_dtypes

df_subset = df.select_dtypes(exclude=[np.number])
# Now apply you can label encode your df_subset
Run Code Online (Sandbox Code Playgroud)

  • 这将包括DateTimes和其他对象dtypes (6认同)

ham*_*x0r 6

我使用两步法:首先确定是否dtype==object,然后如果是,我得到第一行数据以查看该列的数据是否为字符串。

c = 'my_column_name'
if df[c].dtype == object and isinstance(df.iloc[0][c], str):
    # do something 
Run Code Online (Sandbox Code Playgroud)