Допустим, у меня есть следующий набор данных:

import pandas as pd

df = pd.DataFrame(
        {'A': [1, 2, 3],
         'B': ['one', 2, 3],
         'C': [4, 5, '6Y']
         })

Я хотел бы выяснить - без каких-либо громоздких для цикла - какие столбцы содержат по крайней мере один случай с алфавитной буквой (здесь: B и C). Я предполагаю, что результатом должен быть либо список логических значений, либо индексы.

Спасибо за помощь!

4
00schneider 1 Июл 2019 в 17:20

3 ответа

Лучший ответ

В качестве быстрого и простого решения вы можете использовать replace и фильтровать:

df.replace('(?i)[a-z]', '', regex=True).ne(df).any()

A    False
B     True
C     True
dtype: bool

df.columns[df.replace('(?i)[a-z]', '', regex=True).ne(df).any()]
# Index(['B', 'C'], dtype='object')

Другой вариант - применение str.contains по столбцам:

mask = df.astype(str).apply(
    lambda x: x.str.contains(r'[a-z]', flags=re.IGNORECASE)).any()
mask

A    False
B     True
C     True
dtype: bool

df.columns[mask]
# Index(['B', 'C'], dtype='object')
5
cs95 1 Июл 2019 в 14:22

Мы могли бы использовать pd.to_numeric:

df.apply(pd.to_numeric, errors='coerce').isna().any().tolist()
# [False, True, True]

Другой подход может заключаться в использовании applymap с str.isnumeric:

(~df.astype(str).applymap(str.isnumeric).all()).tolist()
# [False, True, True]

5
yatu 1 Июл 2019 в 14:23

В этом случае вы можете сделать с to_numeric

df.apply(pd.to_numeric,errors='coerce').isnull().any()
Out[37]: 
A    False
B     True
C     True
dtype: bool

Обновить

df.stack().str.contains('[a-zA-Z]').groupby(level=1).any()
Out[62]: 
A    False
B     True
C     True
dtype: bool
3
YO and BEN_W 1 Июл 2019 в 14:58