Python 3.x 通过添加组维度的月平均值规范化列值 初始注释
我已经运行了这个程序,但是执行起来需要很长时间。我的数据帧大约有500MB大。我希望听到一些关于如何尽快执行的反馈 问题陈述 我想通过每月列值的Python 3.x 通过添加组维度的月平均值规范化列值 初始注释,python-3.x,pandas,pandas-groupby,Python 3.x,Pandas,Pandas Groupby,我已经运行了这个程序,但是执行起来需要很长时间。我的数据帧大约有500MB大。我希望听到一些关于如何尽快执行的反馈 问题陈述 我想通过每月列值的平均值来规范化数据帧列。更复杂的是,我有一个名为group的列,它表示测量参数(列)的不同传感器。因此,分析需要在组和每个月进行迭代 DF示例 代码(功能正常,但速度较慢) 这是我使用的代码。编码注释提供了大多数行的描述。我知道三个for循环导致了这个运行时问题,但我没有预见到解决这个问题的方法。有人知道吗 #获取各组的月平均值 每月平均值单位=过程数据
平均值
来规范化数据帧列。更复杂的是,我有一个名为group
的列,它表示测量参数(列)的不同传感器。因此,分析需要在组
和每个月进行迭代
DF示例
代码(功能正常,但速度较慢)
这是我使用的代码。编码注释提供了大多数行的描述。我知道三个for循环导致了这个运行时问题,但我没有预见到解决这个问题的方法。有人知道吗
#获取各组的月平均值
每月平均值单位=过程数据。分组依据('group')。重采样('M',how='mean'))
#将最后一行中创建的每月日期存储到名为month_dates的列表中
月日=每个月的平均值。索引。获取级别值(1)
#在多索引列上放置日期。未来注意事项:使用df[日期、颜色名称][单位]访问平均值
mean_per_month_unit=mean_per_month_unit.unstack().swaplevel(0,1,1).排序索引(轴=1)
divide_df=pd.DataFrame().reindex_like(df)
处理列删除('组')
对于组_列表中的grp:
印刷品(玻璃钢)
#逐月迭代
对于月日的mnth:
#制作月和组的面具
掩码=(df.index.month==mnth.month)和(df['group']==grp)
对于过程中的col\u col:
#设置divide_df的值
除法测向iloc[mask.tolist(),除法测向columns.get\u loc(col)]=每月平均测向单位[mnth,col][grp]
#用Divide_df分割进程_df
最终值=过程值/除以值
编辑:示例数据
以下是CSV格式的文件
EDIT2:当前代码(根据当前答案)
def正常化_df(df):
df['month']=df.index.month
打印(df[“月])
df['year']=df.index.year
打印(df['年])
def find_norm(x,df_col_list):#x是数据帧中的一行,col_list是要规范化的列列表
agg=df.groupby(by=['group'、'month'、'year'],as_index=True)。平均值()
印刷品(“#####################”,x.姓名,x[“月])
对于df_col_list中的列:#迭代col list,从聚合中找到平均值,并将值除以
打印(列)
平均值=聚集位置[(x[“集团”]、x[“月”]、x[“年”]、列]
打印(平均颜色)
col_name=“norm”+str(列)
x[colu_name]=x[column]/mean_col#norm
返回x
normalize_cols=df.columns.tolist()
规范化列。删除('组')
#规范化列。删除('模式')
df2=df.apply(查找标准,df列=normalize列,轴=1)
代码在一次迭代中完美运行,然后失败并出现错误:
KeyError: ('month', 'occurred at index 2019-02-01 11:30:17')
正如我所说,它只正确运行一次。但是,它再次迭代同一行,然后失败。根据df.apply()文档,我看到第一行总是运行两次。我只是不知道为什么第二次失败。假设要求按
平均值和月份对列进行分组,下面是另一种方法:
从索引中创建新列-月份和年份。如果索引类型为DatetimeIndex,则可以使用df.index.month
type(df.index)#df是原始数据帧
#pandas.core.index.datetimes.DatetimeIndex
df['month']=df.index.month
df['year']=df.index.year#假设分组发生在每年每个月的每个grp上,则添加年份。如果不考虑年份,则无需添加此列。
现在,对(grp,月,年)
进行分组并汇总,以找到每列的平均值。(假设分组发生在每年每个grp每个月,则添加年份。如果不考虑年份,则无需添加此列。)
agg=df.groupby(by=['grp','month','year',as_index=True)。mean()
使用函数计算规范化值,并在原始数据帧上使用apply()
def find_norm(x,df_col_list):#x是数据帧中的一行,col_list是要规范化的列列表
对于df_col_list中的列:#迭代col list,从聚合中找到平均值,然后将值除以平均值。
平均值=聚集位置[(str(x['grp']),x['month'],x['year'],列]
col_name=“norm”+str(列)
x[colu_name]=x[column]/mean_col#norm
返回x
df2=df.apply(find_norm,df_col_list=['A','B','C',axis=1)
#df2现在将有3个附加列—normA、normB、normC
或者,对于步骤3,可以加入agg
和df
数据帧并找到范数。
希望这有帮助
下面是代码的样子:
#第一步
df['month']=df.index.month
df['year']=df.index.year#假设发生分组,则添加年份
#步骤2
agg=df.groupby(by=['grp'、'month'、'year'],as_index=True).mean()
#步骤3
def find_norm(x,df_col_list):#x是数据帧中的一行,col_list是要规范化的列列表
对于df_col_list中的列:#迭代col list,从聚合中找到平均值,然后将值除以平均值。
平均值=聚集位置[(str(x['grp']),x['month'],x['year'],列]
col_name=“norm”+str(列)
x[colu_name]=x[column]/mean_col#norm
返回x
df2=df.apply(find_norm,df_col_list=['A','B','C',axis=1)
+1感谢@saurjog给出的有益健康的答案!我试图在我的数据上复制这一点,但很难做到。你能用我在帖子中链接的数据(只是在编辑中添加了数据)复制一下吗。如果成功,可以
KeyError: ('month', 'occurred at index 2019-02-01 11:30:17')
df2:
A B C grp month year normA normB normC
2019-02-01 09:30:07 1 2 3 1 2 2019 0.666667 0.8 1.5
2019-03-02 09:30:07 2 3 4 1 3 2019 1.000000 1.0 1.0
2019-02-01 09:40:07 2 3 1 2 2 2019 1.000000 1.0 1.0
2019-02-01 09:38:07 2 3 1 1 2 2019 1.333333 1.2 0.5