我有一个包含许多数值和分类值的数据集,我想只测试数值列的外围值并根据这些列删除行。
我正在尝试这样:
df = df[(np.abs(stats.zscore(df)) < 3).all(axis=1)]
它将删除所有列中的所有外围值,但当然因为我有分类列,我遇到以下错误:
TypeError:+:&#39; float&#39;不支持的操作数类型和&#39; str&#39;
我知道上面的解决方案有效,因为如果我将df
限制为仅包含数字列,那么一切正常但我不想在我的数据框中丢失其余信息从数字列中评估异常值。
答案 0 :(得分:1)
通过排除任何对象(即字符串)列,考虑使用select_dtypes
。
df = df[(np.abs(stats.zscore(df.select_dtypes(exclude='object'))) < 3).all(axis=1)]
使用较小的zscore检查来演示使用随机数据(播种的再现性):
import numpy as np
import pandas as pd
from scipy import stats
LETTERS = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
np.random.seed(1001)
# DATAFRAME OF 50 COLUMNS
df = pd.DataFrame({'NUM1': np.random.randn(50)*100,
'NUM2': np.random.uniform(0,1,50),
'NUM3': np.random.randint(100, size=50),
'CAT1': ["".join(np.random.choice(LETTERS,1)) for _ in range(50)],
'CAT2': ["".join(np.random.choice(['pandas', 'r', 'julia', 'sas', 'stata', 'spss'],1)) for _ in range(50)],
'CAT3': ["".join(np.random.choice(['postgres', 'mysql', 'sqlite', 'oracle', 'sql server', 'db2'],1)) for _ in range(50)]
})
# DATAFRAME OF 11 ROWS
df = df[(np.abs(stats.zscore(df.select_dtypes(exclude='object'))) < 1).all(axis=1)]
print(df) # julia and sql server wins the random draw!
# CAT1 CAT2 CAT3 NUM1 NUM2 NUM3
# 11 I julia sqlite -91.661975 0.443330 73
# 13 I stata sqlite -8.614349 0.668918 69
# 18 H julia db2 39.477287 0.624378 56
# 27 B pandas sql server -26.400278 0.834240 77
# 29 O spss postgres -96.410727 0.748933 45
# 32 Q spss sqlite -49.963199 0.731111 70
# 34 R stata db2 30.983686 0.772178 62
# 36 B julia sql server 72.945459 0.763171 68
# 46 I julia postgres 8.454257 0.387944 39
# 48 Y sas oracle 85.189272 0.842956 43
# 49 F stata sql server -75.488531 0.370730 40