【问题标题】:Eliminate outliers in a dataframe with different dtypes - Pandas消除具有不同 dtype 的数据框中的异常值 - Pandas
【发布时间】:2021-08-05 15:14:06
【问题描述】:

我想消除具有不同数据类型(int64 和对象)的列的数据框中的异常值。我需要删除至少一列中有异常值的所有行。所以,我尝试使用以下代码:

from scipy import stats
df[(np.abs(stats.zscore(df)) < 3).all(axis=1)]

对于每一列,此代码使用列的平均值和标准差计算每个值的 Z 分数。 'all(axis=1)' 保证对于每一行,所有列都满足约束(每个 z-score 的绝对值低于 3)。

但是,由于某些列的 dtype 是 'object',我收到以下错误:TypeError: unsupported operand type(s) for /: 'str' and 'int'

我认为这是因为无法计算只有字符串('object' dtype)的列中的 z 分数。所以,我需要一个只考虑数字列的代码来检测和消除异常值。

您知道如何消除具有不同 dtype(int64 和对象)列的数据框中的异常值吗?

此数据框是关于巴西的房地产租赁的。您可以使用以下代码创建示例:

data = {
    'city': ['São Paulo', 'Rio', 'Recife'],
    'area(m2)': [90, 120, 60],
    'Rooms': [3, 2, 4],
    'Bathrooms': [2, 3, 3],
    'animal': ['accept', 'do not accept', 'accept'],
    'rent($)': [2000, 3000, 800]
}

df = pd.DataFrame(
    data,
    columns=['city', 'area(m2)', 'Rooms', 'Bathrooms', 'animal', 'rent($)']
)

print(df)

这是示例的外观:

       city  area(m2)  Rooms  Bathrooms         animal  rent($)
0  São Paulo        90      3          2         accept     2000
1        Rio       120      2          3  do not accept     3000
2     Recife        60      4          3         accept      800

原始数据集位于:https://www.kaggle.com/rubenssjr/brasilian-houses-to-rent

【问题讨论】:

  • 所以要确认您只想包含 numeric 列的 z-score city 和 animal 列吗?
  • @HenryEcker 是的!没错。

标签: python pandas dataframe outliers


【解决方案1】:

尝试使用select_dtypesdf 获取特定类型的所有列。

要选择所有数字类型,请使用 np.number 或 'number'

new_df = df[
    (np.abs(stats.zscore(df.select_dtypes(include=np.number))) < 3).all(axis=1)
]

【讨论】:

  • 成功了!现在,我意识到我可以指定我想要的列: (np.abs(stats.zscore(df.[['area','Rooms','Bathrooms','rent($)']]))
  • 是的,因为它们是已知的,所以你可以拥有。但是,如果其他人正在尝试做类似的事情,这仍然是一个有用的答案和问题,但是他们正在使用具有更多列的数据集并且按名称选择它们是不可行的。
【解决方案2】:

您可以遍历列并获取每列的 dtypes,并且仅在具有所需类型时才计算异常值。您可以保留要删除的索引的运行列表。像这样的。

drop_idx = []
for cols in df:
    if df[cols].dtype not in (float, int):
        continue
    # grab indexes of all outliers, notice that its '>= 3' now 
    drop_idx.extend(df[np.abs(stats.zscore(df[cols])) >= 3].index))
df = df.drop(set(drop_idx))

【讨论】:

  • 我理解了它背后的逻辑,但代码并没有消除任何行。不过,还是感谢您尝试帮助我。
猜你喜欢
  • 2018-03-14
  • 2021-11-13
  • 2016-08-31
  • 1970-01-01
  • 2015-05-03
  • 1970-01-01
  • 1970-01-01
  • 2022-10-05
  • 2021-03-24
相关资源
最近更新 更多