pandas dataframe数据处理---基于某项目实战

2020/11/10 09:12
阅读数 27

pandas dataframe数据处理

前言

2020年10月有幸进入了大数据这边学着做项目,即笔者在数据挖掘领域的起点,从此开始了漫长的数据处理以及机器学习的项目实战,为了方便队友以及朋友们的数学建模知识储备,将此过程中所学所用整理于此(部分为实战代码)

pandas----yyds

数据的读取与写入

一般我们的数据集的存储形式为excel、csv。

读取
######读取一个csv文件,得到一个dataframe
# 在服务器上的home目录下读取(服务器的jupyter notebook上操作)
bad_data = pd.read_csv('/home/huangpeng/shutdown_mobile_phone.csv')
# 在本地机器上读取(本地的jupyter notebook)
data = pd.read_csv(r'C:\\Users\\Haotong Sun\\Desktop\\HP\\Project\\result\\result\\....csv',engine='python')
# 上面路径前的'r'是为了防止\t的转义,保留字符原始值,不加r有可能会报错~

######批量读取csv文件,得到相应数量的dataframe,并且将其合并为一个dataframe(服务器与本地的代码相同,修改路径即可)
import re
# 1、设置路径和文件名
path = '/home/huangpeng/new_computed_feature_csv/'
files = os.listdir(path)
files_csv = list(filter(lambda x: x[-4:]=='.csv',files))  # 正则筛选文件名后四位为'.csv'的文件
num_filter = re.compile(r'\d+')
data_list = []
# 2、批量读取csv文件并转成若干dataframe组成的列表(data_list)
for file in files_csv:
    # 将每个csv转成一个pd.dataframe
    tmp = pd.read_csv(path + file)
    # 设置pandas的dataframe的columns(列索引)
    columns = ["n","call","called","avg","short" \
                        ,"long","user","ring","call_die","max"]
    tmp.columns = columns
    # 把每个pd.dataframe放入一个列表中
    data_list.append(tmp)
# 3、合并若干个dataframe,得到具有全量数据的dataframe
pd_all_df = pd.concat(data_list)
写入
# 在本地机器上写入一个csv文件
df.to_csv(path_or_buf='C:\\Users\\Haotong Sun\\Desktop\\HP\\Project\\result\\temp.csv')
# 在本地机器上写入一个excel文件
df.to_excel('C:\\Users\\Haotong Sun\\Desktop\\HP\\Project\\result\\temp.xlsx')

pandas.dataframe的基本操作

对于dataframe的常用处理有创建、基本信息获取、行列读取、插入、合并、以及两个dataframe的交互处理等…

创建
data = {
   
   "number":['17345971216','18980452661','19981975787','18180945652','19162962272'],
        'name':['11','22','33','44','55'],
        'ares_code':['22','33','44','55','66']}
df = pd.DataFrame(data,index=['one','two','three','four','five'], \
               columns=['number','name','ares_code'])

# dataframe.values返回相应的numpy下的array对象
df.values
'''array([['17345971216', '11', '22'],
       ['18980452661', '22', '33'],
       ['19981975787', '33', '44'],
       ['18180945652', '44', '55'],
       ['19162962272', '55', '66']], dtype=object)'''
基本信息获取
# dataframe.index返回行索引
df.index
'''Index(['one', 'two', 'three', 'four', 'five'], dtype='object')'''

# dataframe.columns返回列索引
df.columns
'''Index(['number', 'name', 'ares_code'], dtype='object')'''

# dataframe.axes返回行列索引
df.axes
'''[Index(['one', 'two', 'three', 'four', 'five'], dtype='object'),
 Index(['number', 'name', 'ares_code'], dtype='object')]'''

# dataframe.info():打印df的信息
df.info()

# dataframe.describe():按列进行描述性统计,生成一个描述性统计表格
df.describe()

# 显示前n行或后n行数据
df.head(2)
df.tail(2)
按行列读取
################按列读取
######1、df.列索引   --》返回Series对象
df.number
######2、df['列索引'] == df.列索引   --》返回Series对象
df["number"]
df["number","name"]
######3、df.iloc[:,colNo] (colNo:0开始的列号) --》返回dataframe对象
df.iloc[:,2]
df.iloc[:,0:2] # 取前三列

################按行读取
######1、df.loc[['行索引']]  --》返回dataframe对象
df.loc[['one','two']] 
######2、df.iloc[['行号']]   --》返回dataframe对象
df.iloc[[1]]

################获取单元格
df['number']['one']
插入及合并
######在任意位置插入
# df.insert(loc, column, value) loc:插入的列号,column:列索引,value:列数据(列表)
df.insert(0,'number',['17680945652', '00', '88'])
'''	  call	   number name ares_code
one		1	17345971216	11	22
two		2	18980452661	22	33
three	3	19981975787	33	44
four	4	18180945652	44	55
five	5	19162962272	55	66'''

######添加新的一列到末尾
df["called"] = df["call"]
'''	  call	  number	name ares_code called
one		1	17345971216	 11		22		1
two		2	18980452661	 22		33		2
three	3	19981975787	 33		44		3
four	4	18180945652	 44		55		4
five	5	19162962272	 55		66		5'''

######按行列合并
# 按行合并
pd.concat([df,df1],axis=1)
# 按列合并
pd.concat([df,df2],axis=0)
df.append(df2)

在特征矩阵中做标记(label)(使用分类模型前的操作)

接下来的样例处理的数据是原始特征矩阵数据,我们只想对其中在另一个数据集中出现的号码进行分析,则需要做标记(在另一个数据集中出现的标为1,否则为0),那么我们该如何对这个dataframe增加一列label标记呢?

pd_all_df的每一行都是一个号码的各个特征的dataframe,bad_data的numbers列提供了我们需要在pd_all_df中进行标记的号码

# 1、将pd_all_df["number"]与bad_data["numbers"]中的数据进行匹配,若前者的元素在后者中出现,则标记为True,否则为False
pd_label_df = pd_all_df["number"].isin(bad_data["numbers"].values)
# 2、将Series转为dataframe
pd_label_df = pd_label_df.to_frame()
# 3、将True转为1,False转为0
pd_label_df = pd_label_df["number"].apply(lambda x : 1 if x==True else 0)
# 4、在pd_all_df中添加一列,命名为"label",值为pd_label_df中的元素
pd_all_df["label"] = pd_label_df
# 5、从中抽取出label==1的号码
pd_shutdown_df = pd_all_df.loc[pd_all_df["label"]==1]
# 重置行索引,恢复到0开始,步长为1
pd_shutdown_df = pd_shutdown_df.reset_index(drop=True)
特征的标准化/归一化

min-max标准化:

将数据映射至-1到1区间内,以消除特征之间量纲不同的影响。

import numpy as np
def custom_max_min(x):
    minn = np.min(x)
    maxn = np.max(x)
    return (x-minn)/(maxn-minn)

pd_delete_shutdown2["standard_calling_count"] = custom_max_min(pd_delete_shutdown2.calling_count.values)
pd_delete_shutdown2["standard_avg_call_time"] = custom_max_min(pd_delete_shutdown2.avg_call_time.values)
pd_delete_shutdown2["standard_max_talk_time"] = custom_max_min(pd_delete_shutdown2.max_talk_time.values)

Z-score标准化:

有些特征的最大值和最小值相距甚远,若使用min-max标准化会导致大多数的值被映射的值过小,使该特征缺乏了表现力。

此时,如果这些特征近似满足高斯分布,那么使用这种标准化是比较合理的。

import numpy as np
def custom_z_score(x):
    meann=np.mean(x,axis=None)
    delta=sum(abs(x-meann))/len(x)
    return (x-meann)/delta

Z-score改进标准化:

对于本项目,有些特征并不近似满足高斯分布,并且散度过大,平均值无法代表总体的特征,采用中位数能更好的表示总体特征,故我们将Z-score的均值修改为中位数,能达到更佳的效果。

import numpy as np
def custom_z_score(x):
    median=np.median(x,axis=None)
    delta=sum(abs(x-median))/len(x)
    return (x-median)/delta

未完待续

接下来准备整理的内容是项目中的机器学习内容了,由于最近课内作业、期中考以及项目的推进,有空一定肝出来,敬请期待~

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部