数据处理pandas常用代码大全

181 阅读5分钟

数据处理常见代码


一. 读取 log** 数据并转化为 **csv** 格式
with open('./log_data.log', encoding='utf-8') as df:
    log_data = [str(log) for log in df.readlines()]
    csv_data = pd.DataFrame(log_data, columns['log_field'])
二. pandas常见操作
    1. 缺失填充fillna
df = df['col1'].fillna(method='ffill')
# fillna 有三个参数:value、method、limit
# value  特定填充值
# method 填充方法:ffill--用前面的元素填充;bfill--用后面的元素填充
# limit  连续缺失值的最大填充次数
    1. 线性填充
# 一行代码实现多项式填充缺失值
df["value"] = df["value"].interpolate(limit_direction='both')
    1. sklearn填补
from sklearn.impute import SimpleImputer
imp = SimpleImputer(missing_value=np.nan, strategy='constant', fill_value=0)
for col in df.columns:
    df[col] = imp.fit_transform(df[col].values.reshape(-1,1))
# strategy 参数有mean、median、most_frequent、constant
# 其中 constant表示自定义填补
# constant 与 fill_value 配合,fill_value 可填str或数值
    1. 删除 drop
# 删除某些列
df.drop(['columns1', 'column2'], axis=1, inplace=True)
# 删除某些行
df.drop(index=[ind1, ind2, ind5], inplace=True)
    1. dropna/drop_duplicate
df.drop_duplicates(inplace=True)     # 删除重复的行
df.dropna(how='any'or'all')          # 删除有缺失的行
# how 为 'any'表示只要缺失一个值,就删除该行;how 为 'all'表示全部缺失则删除该行
    1. 方向连接 pd.concat()
df = pd.concat([df1, df2], axis=0, ignore_index=False)
# axis=0 横向连接
# axis=1 纵向连接
    1. 关系型连接 pd.merge()
df = pd.merge(df1, df2, on=['field1', 'field2'], how='left')
# on: 根据哪些字段进行横向合并
# how: 聚合方式'left', 'right', 'outer', 'inner'
    1. df.clip(): 数组截断
numpy.clip(a, a_min, a_max, out=None)
"""
a : 输入的数组
a_min: 限定的最小值 也可以是数组 如果为数组时 shape必须和a一样
a_max:限定的最大值 也可以是数组 shape和a一样
out:剪裁后的数组存入的数组
"""
# eg:
np.clip(np.arange(10), 1, 8)
    1. pd.cut(): 对数据从最大值到最小值进行等距划分
    1. pd.qcut(): 按照数据出现频率百分比划分
pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
"""
x : 输入待cut的一维数组
bins : cut的段数,一般为整型,但也可以为序列向量。
right : 布尔值,确定右区间是否开闭,取True时右区间闭合
labels : 数组或布尔值,默认为None,用来标识分后的bins,长度必须与结果bins相等,返回值为整数或者对bins的标识
retbins : 布尔值,可选。是否返回数值所在分组,Ture则返回
precision : 整型,bins小数精度,也就是数据以几位小数显示
include_lowest : 布尔类型,是否包含左区间
"""
pd.qcut(x, q, labels=None, retbins=False, precision=3, duplicates='raise')
    1. df.assign(): 直接对dataframe中添加新的一列
df = pd.DataFrame(data)
df.assign(score=np.random.randint(60,100,size=4))
    1. df.filter(): 根据指定的索引标签对数据框行、或列进行数据筛选(子集查询)
DataFrame.filter(items=None, 
                 like=None, -- str
                 regex=None,  -- str
                 axis=None)
"""
items -- 对列进行筛选 轴标签列表
regex -- 正则匹配
like -- 进行筛选 模糊名查询
axis=0 -- 按行
axis=1 -- 按列
"""
# eg:
df.filter(items=['one', 'three'])
df.filter(regex='e$', axis=1) # 以e结尾
df.one.filter(like='e')       # 模糊查询
df.filter(regex='^r', axis=0).filter(like='o', axis=1) # r开头的行 包含o的列
df.groupby(['A']).filter(lambda x: (x['B'] > 3).any()) # 只要有一个满足
df.groupby('A').filter(lambda x: (x.mean() >= 4).all()) # 全部满足
    1. pd.query(): 使用布尔表达式查询 DataFrame 的列,按照某列规则进行过滤。类似于 SQL 中的 where 进行条件过滤
df.query(expr, inplace=False, **kwargs)
"""
expr -- 查询字符串
inplace -- 是否修改原数据框
"""
# eg:
df.query('B==2')
df.query('A < B')
df.query('A < B & A < C')
df.query('A < B | A < C')
df.query('A not in [3,5]')
    1. 生成交叉表pd.melt():实现将 “宽数据” → “长数据”的一种列转行变换
pandas.melt(frame,
           id_vars=None,
           value_vars=None,
           var_name=None,
           value_name='value',
           col_level=None,
           ignore_index=True)
"""
参数
------------
frame -- 要处理的数据框 DataFrame
id_vars -- 不需要被转换的列名
value_vars -- 需要转换的列名 默认剩余全部
var_name、value_name -- 自定义设置对应的列名
ignore_index -- 是否忽略原始索引
col_level -- 多层索引 MultiIndex
"""
# eg:
pd.melt(df, id_vars=['A'], value_vars=['B', 'C'])
pd.melt(df, id_vars=['A'], value_vars=['B'],var_name='myVarName', value_name='myValueName')
pd.melt(df, id_vars=['A'], value_vars=['B', 'C'],ignore_index=False)
    1. 透视表pd.pivot_table(): 对数据动态排布并且分类汇总的表格格式
pd.pivot_table(df, index=[col1])
pd.pivot_table(df, index=[col1], values=[col3, col4])
pd.pivot_table(df, index=[col1, col2], values=[col3, col4], aggfunc=[np.sum, np.mean], fill_value=0)
    1. 聚合提取 pd.groupby()
# df.groupby(分组依据)[数据来源].使用操作
# 操作具体的一列 进行赋值
feature2_mean = df.groupby(['feature1'])['feature2'].mean()  
# or
feature2_mean = df.groupby(['feature1'])['feature2'].transform('mean')
​
# agg 可以使用多个函数对同一列进行操作
new_df = df.groupby(['feature1', 'feature2'])['feature3'].agg('sum', 'mean').reset_index()
    1. df.sample(): 随机采样
# eg:
df['col1'].sample(n=3, random_state=1)  # series采样
df.sample(frac=0.5, replace=True, random_state=1)  # replace=True: 有放回采样; frac=0.5:下采样。
df.sample(frac=2, replace=True, random_state=1)    # frac=2: 上采样
"""
参数
----------
n: 随机抽样返回的items个数。当frac = None时不可用。
frac: 要返回的 axis items 数量的小数(比例)表示。不能与n一起使用
replace: 是否是有放回取样。
axis: {0 or ‘index’, 1 or ‘columns’, None}, default None
"""
    1. 重采样 pd.resample()
# 时序数据按300s进行聚合,取最大值
series.resample('300s', label='right', closed='right').max()
series.resample('1D').apply(lambda x: x.max() - x.min())
df.resample('%dS' % 60).mean()             # 重新采样
    1. 提取满足时间区间的数据
time_gap_list = []
for i in range(df.shape[0]):
    front_time = str(pd.to_datetime(time_list[i]) - datetime.timedelta(minutes=300))
    end_time = str(pd.to_datetime(time_list[i]) - datetime.timedelta(minutes=300))
    time_gap_list.append([front_time, end_time])
# 后续根据时间区间提取满足的行
    1. dataframe中表格排序变换 sort_values()sort_index()reset_index()rename()
df.sort_values(by=['timestamp'], ascending=True)
# ascending = True(升序) 
# ascending = False(降序)
df.sort_index(inplace=True)
df.reset_index(drop=True, inplace=True)
df.rename(columns={"col1":"name"})
    1. df中某列按时间转换 (年:月:日 时:分:秒 --> 时间戳)And (时间戳 -->年:月:日 时:分:秒)
import time
df['timestamp'] = df['timestamp'].apply(lambda x: int(time.mktime(time.strptime(str(x), "%Y-%m-%d %H:%M:%S"))))
​
# 将时间转换回标准时间格式
df['timestamp'] = df['timestamp'].apply(lambda x: pd.to_datetime(x))
    1. apply/map/transform/filter

    filter和map是python内置函数,可直接调用,apply和transform在pandas模块

    • apply:可直接对dataframe或者series应用函数,也可对pandas中的groupby之后的聚合对象apply函数
    df['col2'] = df['col1'].apply(lambda x: x.sum())   # 一列
    df['col2'] = df.apply(lambda x: x.sum())           # 全部dataframe
    
    • map:求一个序列或多个序列函数映射后的值,常用来转换数据类型,也可接labmda匿名函数
    df['e'].map(float)
    df['d'].map(lambda x: x+3)
    
    • transform: 与内建函数连用速度最快。
    df.transform(lambda x: x + 1)
    
    • filter :过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,可以用filter函数
    x = [1,2,3,4,5,6]
    list(filter(lambda x: x%2 == 0, x))
    # 输出:[2,4,6]
    

    总结:要过滤删减序列用filter;要对多个序列做函数运算用map;在pandas里面直接调用apply,尤其是聚合对象

    1. pd.shift(): 把数据移动指定的位数
df = df.shift(axis=0)  # 向下移动
df = df.shift(periods=-1, axis=0) # 向上移动
df = df.shift(axis=1)  # 向右移动
df = df.shift(periods=-1, axis=1) # 向左移动
    1. pd.rank(): 实现对数据的排序,包括顺序排序、跳跃排序和密集排序等
DataFrame.rank(axis=0,
              method='average',
              numeric_only=None,
              na_option='keep',
              ascending=True,
              pct=False)
"""
参数
-----------
axis -- 0表示按横轴,1表示按纵轴
method -- 排序方式:average、first、min、max、dense
numeric_only -- 是否仅计算数值列
na_option -- 空值处理方式:keep、top、bottom
ascending -- 升序、降序
pct -- 排名百分比
"""
# eg:
data.rank()                # 1.默认按平均值排序 如果两个数值相同 排名为均值
data.rank(method='first')  # 2.根据值在原始数据中出现的顺序进行排名
data.rank(method='min')    # 3.相同数值的排名取最小值
data.rank(method='max')    # 4.相同数值的排名取最大值
data.rank(method='dense')  # 5.相同数值排名不出现跳跃 连续排序
df['total_dense'] = df['total_score'].rank(method='dense', ascending=False) 
def rank_second(x):
    return x[x['score'].rank(method='dense', ascending=False) == 2]
df.groupby('classes').apply(rank_second)          # 提取排名第2的
    1. pandas内置绘图方法(简单易用)
# 简单绘制主状分布图
df['label'].value_counts().plot(kind='bar')
# 聚合后绘制折线图
df.loc[df['label'] != -1].groupby('day')['label'].mean().plot()
​
# 参数 kind
# 'line' -- 折线图
# 'bar'  -- 主状态
# 'barh' -- 横向条形图
# 'hist' -- 柱状图
# 'box'  -- 箱线图
# 'kde'  -- 核密度估计图
# 'pie'  -- 饼状图
# 'scatter'--散点图
    1. pd.rolling(): 主要是用来做移动计算可以对时间进行移动分析
series.rolling(3).sum()
series.rolling(3, min_periods=1).apply(lambda x: sum(x))   # min_periods表示窗口的最小观测值
series.rolling(3, center=True).apply(lambda x: sum(x))   # center=True表示以当前值为中心,往上往下进行筛选,默认只有往上
series.rolling('3D').sum()
series.asfreq("6S", method="ffill")        # 功能同:df.resample('%dS'%6).mean().fillna(method='ffill')
​
df.rolling(3, min_periods=1).agg(lambda x: sum(x))
df.rolling(3, min_periods=1).agg({"col1": "sum", "col2": "mean"})
    1. df.expanding(): 填充rolling()遍历的是移动窗口的数据,而expanding()遍历的是从最开始到当下(min_period)
pd.DataFrame.expanding(min_periods=1, center=False, axis=0)
"""
参数
---------
min_periods:需要有值的观测点的最小数量,决定显示状态,=1表示每个观测点都有值
center:把窗口的标签设置为居中,default False–>居右
axis:default 0:对列进行操作
"""
# eg:
df.expanding(3, axis=1).mean()