您的位置:首页 > 文旅 > 旅游 > 网络违法犯罪网站举报_金华网站建设电话_淘宝关键词查询工具哪个好_长沙网站se0推广优化公司

网络违法犯罪网站举报_金华网站建设电话_淘宝关键词查询工具哪个好_长沙网站se0推广优化公司

2025/3/31 12:05:41 来源:https://blog.csdn.net/qq_66246715/article/details/146293259  浏览:    关键词:网络违法犯罪网站举报_金华网站建设电话_淘宝关键词查询工具哪个好_长沙网站se0推广优化公司
网络违法犯罪网站举报_金华网站建设电话_淘宝关键词查询工具哪个好_长沙网站se0推广优化公司

1.处理缺失数据

总体流程是这样的,

 归根在于如何处理NAN,接下来详细赘述

1.1. 处理缺失值的相关函数
  • 判断缺失值
    • pd.isnull(df):用于判断 DataFrame df 中的元素是否为缺失值(NaN ),返回一个与df 形状相同的布尔型 DataFrame,元素为True 表示对应位置是缺失值。
    • pd.notnull(df):与pd.isnull(df) 相反,判断 DataFrame df 中的元素是否不是缺失值,返回布尔型 DataFrame,元素为True 表示对应位置不是缺失值 。
    • 之后利用np.all()或者np.any就可以知道数据中是否存在NaN。
  • 删除缺失值
    • dropna(axis='rows'):用于删除存在缺失值的行(当axis='rows' 时 )或列(当axis='columns' 时 )。默认axis='rows' ,不会修改原数据,需要接收返回值。例如new_df = df.dropna() ,将返回删除缺失值行后的新 DataFrame。
  • 填充缺失值
    • fillna(value, inplace=False):用指定的value 填充缺失值。inplace=False (默认 )时,不修改原数据,返回填充后的新对象;inplace=True 时,直接在原数据上进行填充修改。例如df.fillna(0, inplace=True) ,将把df 中的缺失值都填充为 0 。
  • 替换数据
    • replace(to_replace, value):用于替换数据。to_replace 是要被替换的值,value 是替换后的值。例如df.replace('?', np.nan) ,将把df 中所有的'?' 替换为NaN 。
1.2. 电影数据的缺失值处理示例
  • 判断缺失值是否存在
import pandas as pd
# 读取电影数据
movie = pd.read_csv("./data/IMDB-Movie-Data.csv")
# 使用pd.notnull判断
not_null_result = pd.notnull(movie)
#返回一个和movie的shape一样的数组,全是布尔型,True为不空,False为空,
#只要结合np.all即可判断是否有空,如果有就是返回False
np.all(not_null_result)
# 使用pd.isnull判断#另一种方法
is_null_result = pd.isnull(movie)
#返回一个和movie的shape一样的数组,全是布尔型,True为不空,False为空,
#只要结合np.any即可判断是否有空,如果有就是返回True
  • 存在缺失值且为np.nan时的处理
    • 删除缺失值
# 不修改原数据
new_movie = movie.dropna()
# 也可重新赋值给原变量
movie = movie.dropna()
  • 填充缺失值
# 填充'Revenue (Millions)'列的缺失值为该列均值
movie['Revenue (Millions)'].fillna(movie['Revenue (Millions)'].mean(), inplace=True)
# 遍历填充所有存在缺失值的列
for i in movie.columns:if np.all(pd.notnull(movie[i])) == False:movie[i].fillna(movie[i].mean(), inplace=True)
  • 缺失值不是np.nan时的处理
import pandas as pd
import numpy as np
# 读取数据(假设数据中有'?'表示缺失值)
wis = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer")
# 替换'?'为np.nan
wis = wis.replace(to_replace='?', value=np.nan)
# 后续再进行缺失值填充等操作,例如填充某列缺失值为均值
wis['column_name'].fillna(wis['column_name'].mean(), inplace=True)
1.3. 处理缺失值的步骤总结
  1. 统一缺失值形式:若存在缺失值但不是np.nan 的形式,使用data.replace(to_replace, value=np.nan) 将其替换为np.nan 。
  2. 判断是否存在缺失值:使用np.all(pd.notnull(data)) ,若结果为True ,表示不存在缺失值,不做处理;若为False ,表示存在缺失值,继续下一步。
  3. 填充缺失值:使用统计学指标值(如均值mean、中位数median等 )对缺失值进行填充,如data['column_name'].fillna(data['column_name'].mean(), inplace=True) 。

2.数据的离散化

2.1. 为什么要离散化

连续属性离散化目的是简化数据结构,减少给定连续属性值个数,常作为数据挖掘工具。比如在分析用户年龄与消费习惯时,年龄是连续属性,将年龄离散化为儿童、青年、中年、老年等区间,可更方便分析不同年龄段消费特征。

2.2. 什么是数据的离散化

连续属性离散化是在连续属性值域上划分若干离散区间,用不同符号或整数值代表落在各子区间的属性值。例如原始身高数据 165, 174, 160, 180, 159, 163, 192, 184 ,按 150 - 165, 165 - 180, 180 - 195 划分区间,可标记为矮、中、高类别。

2.3. 具体实现
  • 读取股票数据
import pandas as pd
# 读取股票数据
data = pd.read_csv("./data/stock_day.csv")
# 筛选出p_change数据
p_change = data['p_change']

此代码先读取股票 CSV 文件数据,再提取出涨跌幅数据p_change ,为后续离散化操作准备数据。

  • 将股票涨跌幅数据进行分组
    • 等频分组(qcut )
# 自行分组,将数据分为10组
qcut = pd.qcut(p_change, 10)
# 计算分到每个组数据个数
qcut.value_counts()

pd.qcut(data, q)中,data是要分组的数据(这里是p_change ),q是要划分的组数(这里为 10 ),它会使每组数据数量尽量相等。value_counts()用于统计每组数据个数,经常结合离散化一起使用

  • 自定义区间分组(cut )
# 自己指定分组区间
bins = [-100, -7, -5, -3, 0, 3, 5, 7, 100]
p_counts = pd.cut(p_change, bins)

pd.cut(data, bins)中,data是数据,bins是自定义区间边界列表(这里bins指定了具体区间 ),按此区间对数据进行分组。也经常结合value_counts()一起使用。

现在我们就通过统计个数得到了一下形式

接下来为了精准的表示每个样本在那个区间可以使用一下编码(one-hot/哑变量)

  • 股票涨跌幅分组数据变成 one - hot 编码
    • one - hot 编码概念:把每个类别生成一个布尔列,每个样本只有一列取值为 1 ,其他为 0 ,又称热编码。例如类别有 Human、Penguin、Octopus、Alien ,编码后每个样本对应这些类别列,只有所属类别列值为 1 。这样又多了四个特征,每个样本表示唯一。
    • 实现代码
# 得出one-hot编码矩阵
dummies = pd.get_dummies(p_counts, prefix="rise")

pandas.get_dummies(data, prefix=None)中,data可以是类似数组、Series 或 DataFrame(这里是分组后的p_counts ),prefix是分组名字(这里为rise ),生成 one - hot 编码矩阵,方便后续机器学习模型处理。这是最后结果。

3.数据的合并

如果数据由多张表构成,需要进行数据合并

1. pd.concat实现数据合并
  • 函数语法及参数
    pd.concat(objs, axis=0, join='outer', ignore_index=False)
    • objs:必填参数,是一个由 DataFrame 或 Series 组成的列表,如[data1, data2] ,表示要合并的对象。
    • axis:可选参数,用于指定合并的轴方向。axis=0(默认值)表示按列索引合并(纵向合并 ),即上下拼接;axis=1表示按行索引合并(横向合并 ),即左右拼接。
    • join:可选参数,指定合并时的连接方式,有'outer'(默认值,取并集 )和'inner'(取交集 )两种。
    • ignore_index:可选参数,布尔值,默认为False 。若为True ,合并后将重新生成行索引。
  • 代码示例
2. pd.merge实现数据合并
  • 函数语法及参数
    pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None)
    • left:必填参数,第一个 DataFrame。
    • right:必填参数,第二个 DataFrame。
    • how:可选参数,指定连接方式,常见取值有:
      • 'inner':内连接(默认值),使用左右 DataFrame 键的交集。
      • 'left':左连接,使用左 DataFrame 的键。
      • 'right':右连接,使用右 DataFrame 的键。
      • 'outer':外连接,使用左右 DataFrame 键的并集。
    • on:可选参数,指定用于合并的共同键列。要求左右 DataFrame 都存在该列
    • left_on:可选参数,指定左 DataFrame 用于合并的键列。
    • right_on:可选参数,指定右 DataFrame 用于合并的键列。
  • 代码示例
import pandas as pd
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],'key2': ['K0', 'K1', 'K0', 'K1'],'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],'key2': ['K0', 'K0', 'K0', 'K0'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']})
# 默认内连接
result_inner = pd.merge(left, right, on=['key1', 'key2'])
# 左连接
result_left = pd.merge(left, right, how='left', on=['key1', 'key2'])
# 右连接
result_right = pd.merge(left, right, how='right', on=['key1', 'key2'])
print("内连接结果:\n", result_inner)
print("左连接结果:\n", result_left)
print("右连接结果:\n", result_right)

此代码先创建了两个 DataFrame left 和right ,然后分别展示了内连接、左连接和右连接的合并结果。

拓展一下连接:

其实和数据库的一样,内连接就是筛选数据,没有相同的键值的数据被排除

外连接就是分别遍历左右表,如果另一个表有相同的键值的全部列出来,直到左右两表被全部遍历完。左连接和右连接其实是特殊的外连接,就是只遍历左表或者右表。

4.交叉表和透视表(交叉表是一列特征在另一列特征上的数量,透视表是占比但其实进过计算交叉表除以和还是透视表) 

 案例分析

1 数据准备
  • 提取日期对应的星期数
import pandas as pd
import numpy as np
# 假设data是包含股票数据的DataFrame,其索引为日期
date = pd.to_datetime(data.index).weekday
data['week'] = date

pd.to_datetime() 将索引的日期字符串转换为日期时间格式,.weekday 方法获取对应的星期数(0 代表星期一,1 代表星期二,以此类推 ),并将其作为新列week 添加到data 中。

内容拆解:

47行数据不可以用,所以要转化为可以使用的数据,接下来就可以取出对应的年月日了

  • 将涨跌幅数据分类
data['posi_neg'] = np.where(data['p_change'] > 0, 1, 0)

np.where() 函数根据条件判断,当data['p_change'] 大于 0 时,对应位置赋值为 1 (代表涨幅为正 ),否则赋值为 0 (代表涨幅为负或持平 ),并将结果存储在新列posi_neg 中,用来形成交叉表。

  • 交叉表计算
count = pd.crosstab(data['week'], data['posi_neg'])

pd.crosstab() 函数根据data['week'] 和data['posi_neg'] 生成交叉表,统计每个星期数下涨跌幅为正(1 )和为负或持平(0 )的天数。

结果为现在就是交叉表了,我们展示占比(也就是透视表)

  • 计算比例
sum = count.sum(axis=1).astype(np.float32)
pro = count.div(sum, axis=0)

count.sum(axis=1) 计算交叉表中每一行(每个星期数 )的总数,.astype(np.float32) 将数据类型转换为 32 位浮点数。count.div(sum, axis=0) 进行除法运算,axis=0 表示按列方向,将交叉表的每一列除以对应的行总数,得到每个星期数下涨跌幅为正和为负或持平的比例。pro如下图:

2 查看效果
import matplotlib.pyplot as plt
pro.plot(kind='bar', stacked=True)
plt.show()

pro.plot(kind='bar', stacked=True) 使用matplotlib 库绘制堆叠柱状图,kind='bar' 指定为柱状图类型,stacked=True 表示堆叠显示,便于直观对比每个星期数下涨跌幅正负的比例情况。plt.show() 显示绘制的图形。如下图

 如不堆叠显示,图会如下:

3.其实我们可以直接得到一列数据的占比,使用透视表即可:

2.3 使用pivot_table(透视表)实现

  • 函数语法及参数
    pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False)
    • data:必填参数,为要操作的 DataFrame 对象,这里是包含股票数据及相关衍生列(如weekp_n等 )的data 。
    • values:可选参数,接收列名组成的列表,指定要进行聚合计算的列。这里['posi_neg']["p_n"] 表示对涨跌幅正负标记列进行操作。
    • index:可选参数,指定用于分组的索引列,这里'week' 表示按星期数分组。
    • columns:可选参数,用于指定列分组依据,若不指定则不进行列方向分组。
    • aggfunc:可选参数,默认'mean' ,用于指定聚合函数。常见的有'sum'(求和)、'count'(计数)等。这里默认求均值,对于 0 和 1 组成的涨跌幅正负标记列,均值就相当于涨幅为正的比例。
    • fill_value:可选参数,用于指定填充缺失值的值。
    • margins:可选参数,布尔值,默认为False ,若为True 会添加总计行和总计列。
  • 代码示例
import pandas as pd
# 假设data是包含股票数据及相关衍生列(如week、p_n等)的DataFrame
result = data.pivot_table(["p_n"], index="week")
print(result)

此代码通过pivot_table 函数,以week 列为索引,对p_n 列(涨跌幅正负标记列 )进行聚合操作(默认求均值 ),直接得到每个星期数下涨幅为正的比例,相较于之前交叉表计算等步骤更为简洁。结果如下:

5.分组与聚合(两个类似于数据库,经常结合在一起使用,只有分组没有聚合只会返回一个对象没有意义。)

一个简单的图:

分组 API

DataFrame.groupby函数
  • 函数语法及参数
    DataFrame.groupby(key, as_index=True)
    • key:必填参数,用于指定分组的列数据,可以是单个列名,也可以是列名组成的列表。比如['color'] ,表示按color列进行分组。
    • as_index:可选参数,布尔值,默认为True 。当as_index=True 时,分组的键(这里是color列的值 )会作为结果的索引;当as_index=False 时,分组的键会作为结果的一列保留,数据结构保持不变。
  • 案例讲解
    • 数据准备
import pandas as pd
col = pd.DataFrame({'color': ['white','red', 'green','red', 'green'],'object': ['pen', 'pencil', 'pencil', 'ashtray', 'pen'],'price1': [5.56, 4.20, 1.30, 0.56, 2.75],'price2': [4.75, 4.12, 1.60, 0.75, 3.15]})

此代码创建了一个 DataFrame col ,包含color(颜色)、object(物品)、price1price2(价格)四列数据。

  • 分组聚合操作
    • as_index=True 情况(默认 )
# 分组,求平均值
col.groupby(['color'])['price1'].mean()
col['price1'].groupby(col['color']).mean()

这两种写法等价,都是按color列对price1列进行分组并求平均值。运行后,color列的值作为索引,得到不同颜色对应的price1平均值:

color
green    2.025
red      2.380
white    5.560
Name: price1, dtype: float64
  • as_index=False 情况
col.groupby(['color'], as_index=False)['price1'].mean()

此代码按color列对price1列进行分组并求平均值,同时设置as_index=False ,此时color列作为结果的一列保留,得到:

  color  price1
0 green  2.025
1   red  2.380
2 white  5.560

通过groupby函数结合聚合函数(如mean ),可以方便地对数据进行分组聚合操作,分析不同组别的数据特征 。

为什么要在group后边加上具体的列呢?

明确聚合对象

groupby 函数实现分组后,需要对特定的列进行聚合计算(这里是求平均值,使用mean 函数 )。col 这个 DataFrame 可能包含多列数据(如案例中还有objectprice2 等列 ),通过指定['price1'] ,就明确告诉程序是要对price1 这一列的数据进行聚合操作。如果不指定,程序就不知道具体要对哪列数据进行后续的聚合计算,会引发错误。

符合逻辑操作流程

分组聚合操作的逻辑是先分组,然后对组内的某列或某些列数据进行聚合。比如在这个案例中,我们想知道不同颜色对应的price1 价格的平均值,所以要指定price1 列。如果我们想分析price2 列,就需要指定['price2'] ,如col.groupby(['color'])['price2'].mean() 。

注意,仔细观察两种方法的不同之处,group里的代码一个直接用列名一个不能:

col['price1'].groupby(col['color']).mean() 这种针对 Series 对象进行groupby 操作的情境下,不能直接用列名。

因为col['price1'] 已经是一个 Series 对象,当对它调用groupby 方法时,groupby 函数期望传入一个与该 Series 长度一致的可迭代对象(通常也是一个 Series )来确定分组规则。如果直接写列名,比如col['price1'].groupby('color').mean() ,程序会报错,因为'color' 只是一个字符串,不是与col['price1'] 长度相同的可迭代对象,无法明确分组逻辑。

 

而在基于 DataFrame 进行groupby 操作时,像col.groupby(['color'])['price1'].mean() ,可以直接用列名(以列表形式 )来指定分组依据,这是因为 DataFrame 的groupby 方法有相应的机制去识别和处理列名列表作为分组键

当group中分组依据是一个列表的时候就好像是先按第一个分,然后一次分组:

首先这张图,表示了如果使用汇总聚合函数,并不需要指定列,因为只是统计个数的话不需要明确。

第二展示了列表分组规律

6.整体电影数据案例

关于问题1 很简单

关于问题2:

因为只用pandas绘图简单无法进行刻度的设置,注意这里数据是加了.values,因为如果不加他是一个series的格式,这样有索引,你需要用值所以是.values所以需要用matplotlib进行绘图结果如下:

 但是发现刻度不对,我们需要对上,所以可以将数据的max与min之间的数分21个(因为是设置了20组,需要21个数),用linspace生成等距的数即可。

关于问题3 

我们首先要知道所有电影的种类(因为每个电影种类很多且有重复,可以使用unique来进行去重)

接着生成一个全0列表行数为电影数列数为电影种类,之后我们可以循环每个电影对应的种类,如果是某个类型即为1,最后按列求和就可以知道具体有多少了

解释一下那个分割:首先如果不用按逗号分割列表里每个元素是这样的:

类型之间按逗号分割

所以要按逗号分割于是可以单独提出类型列表,因为i.split返回值就是列表,所以组成了列表嵌套

之后使用双循坏就可以取出每个值了,然后在去重即可,如下图:

然后生成一个按电影为行,按类型为列的dataframe即可

之后循坏完毕按列求和即可

之后排序绘图即可

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com