1. 查看表信息
df.info()
df.dtypes # 查看列的类型
df.columns # 查看所有列名
df['A'].value_counts() # 查看某列不同值的数量
df.isnull().sum() # 查看每列缺失值个数(import numpy)
df['A'].nunique() # 查看某列有多少个不同的值
df.duplicated().sum() # 查看表中是否存在重复行(import numpy)
2. one-hot 编码
对 DataFrame 对象进行 one-hot 编码(不包括二分类)
import numpy as np
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(drop='if_binary') # drop='if_binary'代表去除二分类的列
one_hot_encoded_data = encoder.fit_transform(df).toarray()
encoder.categories_ # 查看每列对应的类别
在 DataFrame 转换成独热编码后保留列名,需要自己写操作,并没有现成的函数:
import numpy as np
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(drop='if_binary') # 创建编码对象
# 提取原始的列名称
col_names = df.columns.tolist()
# 新编码字段名称列表
new_col_names = []
# 提取 one-hot 编码后所有特征的名称
for i, j in enumerate(col_names):
if len(encoder.categories_[i]) == 2:
new_col_names.append(i)
else:
for f in encoder.categories_[i]:
feature_name = j + '_' + f
new_col_names.append(feature_name)
# 组合成新的 DataFrame
pd.DataFrame(encoder.fit_transform(df).toarray(), columns=new_col_names)
3. 连续值分箱(连续值转换离散值)
import pandas as pd
import numpy as np
from sklearn.preprocessing import KBinsDiscretizer
df = pd.DataFrame({'A': [0, 10, 180, 50, 30, 55, 99, 80, 75, 10, 300]})
# 特征必须是列向量,不然 KBinsDiscretizer 无法识别
income = np.array(df['A']).reshape(-1, 1)
# 等宽分箱:分组间隔相同(strategy='uniform')
# dis = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
# 等频分箱:每组元素个数相同,如果除不尽,余数放最后一组(strategy='quantile')
# dis = KBinsDiscretizer(n_bins=2, encode='ordinal', strategy='quantile')
# 聚类分箱:通常优先使用(strategy='kmeans')
dis = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='kmeans')
dis.fit_transform(income) # 对特征进行分箱操作
dis.bin_edges_ # 查看分箱的边界
4. 分组统计 + 特征衍生
import pandas as pd
df_0 = pd.DataFrame({'A': [1, 1, 2, 3, 2],
'B': [1, 2, 2, 3, 1],
'C': [29, 31, 64, 95, 11],
'D': [1, 2, 3, 4, 5]})
# 取出 A B C 三列
df = df_0[['A', 'B', 'C']]
# 以A列分组,其他列按照分组求均值
df.groupby('A').mean()
# 按照多列分组
df.groupby(['A', 'B'])
# 对其他列按照分组进行多种计算
df.groupby('A').agg(['min', 'max', 'mean']).reset_index()
# 对部分列按照分组对不同列进行不同计算
data = df.groupby('A').agg({'B': ['min', 'max', 'mean'], 'C': ['max']}).reset_index()
# 修改列名称
data.columns = ['A', 'B_A_max', 'B_A_min', 'B_A_mean', 'C_A_max']
# 以 A 列为主键拼接group_by后的数据和原始数据
df_all = pd.merge(df_0, data, how='left', on='A')
对于连续型变量的统计可以使用的方法:
- mean / var:均值、方差
- max / min :最大值最小值
- skew:数据分布偏度,小于0时左偏,大于0时右偏
对于分类变量,还有这些连续型变量的统计方法:
- median:中位数
- count:个数统计
- nunique:类别数
- quantile:分位数
对于分位数,需要通过自定义函数实现:
def q1(x):
# 计算下四分位数
return x.quantile(0.25)
def q2(x):
# 计算上四分位数
return x.quantile(0.25)
aggs = {'B': [q1, q2]} # 计算B列的上四分位数、下四分位数
df.groupby('A').agg(aggs).reset_index()
5. 时序特征处理 + 特征衍生
DataFrame 中的时间列转换为 datetime 类型:
t['time'] = pd.to_datetime(t['time']) # 将time列转换为datetime类型
调整精度:
t['time'].values # 将时间列转换为ndArray对象,但是ndArray默认精度为纳秒(ns)
t['time'].values.astype('datetime64[D]') # 将精度调整为天
t['time_D'] = t['time'].values.astype('datetime64[D]') # 添加一个时间为天的列
根据时间特征计算并添加其他特征列:
t['year'] = t['time'].dt.year # 年
t['month'] = t['time'].dt.month # 月
t['day'] = t['time'].dt.day # 日
t['hour'] = t['time'].dt.hour # 时
t['minute'] = t['time'].dt.minute # 分
t['second'] = t['time'].dt.second # 秒
t['quarter'] = t['time'].dt.quarter # 季度
t['dayofweek'] = t['time'].dt.dayofweek + 1 # 周几,从0开始,需要+1
t['dayofyear'] = t['time'].dt.dayofyear # 一年中的第几天
t['hour_section'] = (t['hour'] // 6).astype(int) # 查看是凌晨、上午、下午、晚上
计算时间差:
# 计算时间差,结果为timedelta类型
t['time'][1] - t['time'][0] # 元素相减
t['time'] - pd.Timestamp('2024-01-01 00:00:00') # 与固定时间相减
t['time_diff'] = t['time_1'] - t['time_2'] # 列相减
# 粗略计算
t['time_diff'].dt.days # 天
t['time_diff'].dt.seconds # 秒(只在时、分、秒维度计算,不考虑天)
np.round(t['time_diff'].dt.days / 30).astype('int') # 月
# 精确计算
t['time_diff'].values # 返回纳秒计算结果
t['time_diff'].values.astype('timedelta64[h]') # 时
t['time_diff'].values.astype('timedelta64[s]') # 秒
# 如果要拼接到表中,需要再转换为int类型
t['time_diff_s'] = t['time_diff'].values.astype('timedelta64[s]').astype(int)
关键时间点的选取:
import datetime
# 起止时间的选取
t['time'].max()
t['time'].min()
# 获取当前时间,默认获取的时间是毫秒级(ms)
cur_time = datetime.datetime.now()
pd.Timestamp(cur_time) # 转换为pandas的datetime类型
# 自定义时间输出格式,并借此输出指定精度的时间
pd.Timestamp(cur_time.strftime('%Y-%m-%d %H:%M:%S'))
6. 方差分析(Analysis of Variance, ANOVA)
df.dropna(subset=['A', 'B'])
缺失值处理
df.dropna(subset=['A', 'B'])
其他操作
保存为csv(不带index)
df.to_csv('/path/filename.csv', index=False) # 保存csv
df.to_csv('/path/filename.txt', index=False, sep='|') # 保存txt,并设置分隔符
pandas遍历表时添加进度条:
from tqdm import tqdm
for i in tqdm(df.iteritems(), total=df.shape[0]):
time.sleep()
pandas将连续值按照范围转换为离散值
# 将年龄按照10为间隔划分
data['age_range'] = pd.cut(data['age'], list(range(0, 101, 10)))