【数据准备和特征工程】数据清理

本文详细介绍了数据清理过程,包括数据类型转换、处理重复值、缺失数据检测与填充(如使用Z-Score和IQR方法),以及如何识别并处理离群值。通过实例演示了pandas库在数据清洗中的应用,是数据科学家必备技能之一。
摘要由CSDN通过智能技术生成

1.基本概念

import pandas as pd df = pd.read_csv("test.csv") df.sample(10)

获取前几行数据

data.head()

获取数据维度信息

df.shape

获取数据表属性的相关信息

data.info()

获取数据表属性类型信息

data.head()

2.转换数据类型

import pandas as pd
df = pd.DataFrame([{'col1':'a', 'col2':'1'},
{'col1':'b', 'col2':'2'}])
df.dtypes

Object转换为数值型

df['col2-int'] = df['col2'].astype(int)

含有不是数字的Object类型转换为数值型

#此时由于含有不是数字的值,所以就算忽略报错后转换后的类型还是Object
s = pd.Series(['1', '2', '4.7', 'pandas', '10'])
s.astype(float,errors='ignore')
#这种方法可以将其转换为数值型,Pandas则变为Nan
pd.to_numeric(s, errors='coerce')

转换为日期类型

#可以将三列数据Month、Day、Year转换为日期类型的数据
pd.to_datetime(df[['Month', 'Day', 'Year']])

最终的代码

import pandas as pd

import numpy as np

  

def convert_money(value):

new_value = value.replace(",","").replace("$","")

return float(new_value)

  

df2 = pd.read_csv("/home/aistudio/data/data20506/sales_types.csv",

dtype = {'Customer Number': 'int'},

converters = {'2016': convert_money,

'2017': convert_money,

'Percent Growth': lambda x: float(x.replace("%", "")) / 100,

'Jan Units': lambda x: pd.to_numeric(x, errors='coerce'),

'Active': lambda x: np.where(x =='Y', 1, 0),

})

df2['Date'] = pd.to_datetime(df[['Month', 'Day', 'Year']])

df2

3.处理重复数据

import pandas as pd
d = {'Name':['Newton', 'Galilei', 'Einstein', 'Feynman', 'Newton', 'Maxwell', 'Galilei'],
'Age':[26, 30, 28, 28, 26, 39, 40],
'Score':[90, 80, 90, 100, 90, 70, 90]}
df = pd.DataFrame(d,columns=['Name','Age','Score'])
df

df.duplicated()函数使用

Consider dataset containing ramen rating.

>>> df = pd.DataFrame({
...     'brand': ['Yum Yum', 'Yum Yum', 'Indomie', 'Indomie', 'Indomie'],
...     'style': ['cup', 'cup', 'cup', 'pack', 'pack'],
...     'rating': [4, 4, 3.5, 15, 5]
... })
>>> df
    brand style  rating
0  Yum Yum   cup     4.0
1  Yum Yum   cup     4.0
2  Indomie   cup     3.5
3  Indomie  pack    15.0
4  Indomie  pack     5.0

By default, for each set of duplicated values, the first occurrence
is set on False and all others on True.

>>> df.duplicated()
0    False
1     True
2    False
3    False
4    False
dtype: bool

By using 'last', the last occurrence of each set of duplicated values
is set on False and all others on True.

>>> df.duplicated(keep='last')
0     True
1    False
2    False
3    False
4    False
dtype: bool

By setting ``keep`` on False, all duplicates are True.

>>> df.duplicated(keep=False)
0     True
1     True
2    False
3    False
4    False
dtype: bool

To find duplicates on specific column(s), use ``subset``.

>>> df.duplicated(subset=['brand'])
0    False
1     True
2    False
3     True
4     True
dtype: bool

删除重复的

#保留第一个
df.drop_duplicates()
#保留最后一个重复的元素
df.drop_duplicates('Age', keep='last')

4.处理缺失数据

a.检查缺失数据
#方法一
#isna()函数,若为空则为False,若不为空则为True
df = pd.DataFrame({"one":[1, 2, np.nan], "two":[np.nan, 3, 4]})
df.isna() #返回m行n列,每个元素的值都会返回(True,False)
df.isna().any() #只返回1列,只要有一个是False就整个属性的值就为False
#方法二
#可以统计缺失率
(data.shape[0] - data.count()) / data.shape[0]
b.直接删除缺失数据

Dropna()函数

Examples
--------
>>> df = pd.DataFrame({"name": ['Alfred', 'Batman', 'Catwoman'],
...                    "toy": [np.nan, 'Batmobile', 'Bullwhip'],
...                    "born": [pd.NaT, pd.Timestamp("1940-04-25"),
...                             pd.NaT]})
>>> df
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT

Drop the rows where at least one element is missing.

>>> df.dropna()
     name        toy       born
1  Batman  Batmobile 1940-04-25

Drop the columns where at least one element is missing.

>>> df.dropna(axis='columns')
       name
0    Alfred
1    Batman
2  Catwoman

Drop the rows where all elements are missing.

>>> df.dropna(how='all')
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT

Keep only the rows with at least 2 non-NA values.

>>> df.dropna(thresh=2)
       name        toy       born
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT

Define in which columns to look for missing values.

>>> df.dropna(subset=['name', 'born'])
       name        toy       born
1    Batman  Batmobile 1940-04-25

Keep the DataFrame with valid entries in the same variable.
在同一个变量改变
>>> df.dropna(inplace=True)
>>> df
     name        toy       born
1  Batman  Batmobile 1940-04-25

c.用指定值填补缺失数据
df = pd.DataFrame({'ColA':[1, np.nan, np.nan, 4, 5, 6, 7], 'ColB':[1, 1, 1, 1, 2, 2, 2]})

df['ColA'].fillna(method='ffill')#以前面一个值填充

df['ColA'].fillna(method='bfill')#以后面一个值填充

调用sklearn.impute中的SimpleImputer来填补缺失数据

from sklearn.impute import SimpleImputer

#以均值填充空值
imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean') 
col_values = imp_mean.fit_transform(pdf2['Height-na'].values.reshape((-1, 1)))

#以常数填充空值
df = pd.DataFrame({"name": ["Google", "Huawei", "Facebook", "Alibaba"],"price": [100, -1, -1, 90]})

imp = SimpleImputer(missing_values=-1, strategy='constant', fill_value=110) # ⑤

imp.fit_transform(df['price'].values.reshape((-1, 1)))
d.根据规律填补缺失值

利用sklearn.linear_model的LinearRegression来回归未知的数据

df = pd.DataFrame({"one":np.random.randint(1, 100, 10),
"two": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20],
"three":[5, 9, 13, np.nan, 21, np.nan, 29, 33, 37, 41]})

from sklearn.linear_model import LinearRegression # ⑥
df_train = df.dropna() #训练集
df_test = df[df['three'].isnull()] #测试集

regr = LinearRegression()
regr.fit(df_train['two'].values.reshape(-1, 1), df_train['three'].values.reshape(-1, 1)) # ⑦
df_three_pred = regr.predict(df_test['two'].values.reshape(-1, 1)) 

# 将所得数值填补到原数据集中
df.loc[(df.three.isnull()), 'three'] = df_three_pred

df

使用sklearn.ensemble的RandomForestRegressor来进行预测

import pandas as pd
train_data = pd.read_csv("/home/aistudio/data/data20507/train.csv")
train_data.info() 

df = train_data[['Age','Fare', 'Parch', 'SibSp', 'Pclass']] #可能跟年龄有关的特征
known_age = df[df['Age'].notnull()].values
unknown_age = df[df['Age'].isnull()].values

y = known_age[:, 0]
X = known_age[:, 1:]

from sklearn.ensemble import RandomForestRegressor # ⑩
rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1) # ○11
rfr.fit(X, y)

pred_age = rfr.predict(unknown_age[:, 1:]) # ○13
pred_age.mean()

train_data.loc[(train_data.Age.isnull()), 'Age'] = pred_age
train_data.isna().any()

还可以利用KNN来填补缺失值

%matplotlib inline
import seaborn as sns
from sklearn.datasets import load_iris # 引入鸢尾花数据集
import numpy as np

iris = load_iris()
X = iris.data

# 制造含有缺失值的数据集
rng = np.random.RandomState(0)
X_missing = X.copy()

mask = np.abs(X[:, 2] - rng.normal(loc=5.5, scale=0.7, size=X.shape[0])) < 0.6

X_missing[mask, 3] = np.nan # X_missing是包含了缺失值的数据集

from missingpy import KNNImputer # 引入KNN填充缺失值的模型
imputer = KNNImputer(n_neighbors=3, weights="uniform")
X_imputed = imputer.fit_transform(X_missing)

#填补之前的数据分布
sns.distplot(X.reshape((-1, 1)))
#填补缺失数据后的分布
sns.distplot(X_imputed.reshape((-1, 1))) 

5.离群数据

5.1 通过可视化
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.datasets import load_boston

boston = load_boston()
x = boston.data
y = boston.target
columns = boston.feature_names
 
#create the dataframe
boston_df = pd.DataFrame(x)
boston_df.columns = columns
boston_df.head()
Box-plot
import seaborn as sns
sns.boxplot(x=boston_df['INDUS']);

![[箱线图.png]]

sns.boxplot(x=boston_df['PTRATIO']);
sns.boxplot(x=boston_df['DIS']);
Scatter-plot
fig, ax = plt.subplots(figsize=(16,8))
ax.scatter(boston_df['INDUS'], boston_df['TAX'])
ax.set_xlabel('Proportion of non-retail business acres per town')
ax.set_ylabel('Full-value property-tax rate per $10,000')
plt.show();
5.2 通过数学计算
Z-Score

Z-Score是指观测点或数据的值超过观测值或测量值平均值的标准差的符号数。

from scipy import stats
import numpy as np
z = np.abs(stats.zscore(boston_df))
print(z)

threshold = 3
print(np.where(z > 3))
IQR score

四分位数范围(IQR),又称平均数或50%平均数,或技术上称为H-spread,是衡量统计学分散度的指标,等于75%和25%之间的差值,或上四分位数和下四分位数之间的差值,IQR=Q3 - Q1。百度百科解释
![[IQR.png]]

Q1 = boston_df.quantile(0.25)
Q3 = boston_df.quantile(0.75)
IQR = Q3 - Q1
print(IQR)

既然我们现在有了IQR估计,那么就可以选择离群值。下面的代码将产生带有真值和假值的结果。带有False的数据点表示这些值是有效的,而True则表示有释放。

print((boston_df < (Q1 - 1.5 * IQR)) | (boston_df > (Q3 + 1.5 * IQR)))
5.3 处理离群数据
  • 识别异常值–分析有无异常值的结果模型–做出结论。
  • 如果你确定数值是错误的,就修正它。
  • 如果离群值不在利益分配范围内,则删除。
  • 考虑到数据的差距,使用抗离群值的统计工具,例如,稳健回归(用另一种参数估计方法)Robust_regression。
  • 离群值的常见原因是两种分布的混合,可能是两个不同的子人群,也可能表明 "测量正确 "和 “测量误差”;这通常是由混合模型来建模。 (Mixture model).

参考资料

https://blog.csdn.net/weixin_42199542/article/details/106898892
https://blog.csdn.net/bbbeoy/article/details/72124004

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独行者~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值