基于日期时间列名称的数据框的条件平均值

Posted

技术标签:

【中文标题】基于日期时间列名称的数据框的条件平均值【英文标题】:Conditional mean of a dataframe based on datetime column names 【发布时间】:2021-07-22 04:03:24 【问题描述】:

我是 python 新手。我正在寻找一种方法来根据列名生成行值的平均值(列名是从 1 月到 12 月的日期系列格式)。我想在一年的时间里每 10 天生成一次平均值。我的数据框采用以下格式(2000 行)

import pandas as pd
df= pd.DataFrame('A':[81,80.09,83,85,88],
                  'B':[21.8,22.04,21.8,21.7,22.06],
                  '20210113':[0,0.05,0,0,0.433],
                  '20210122':[0,0.13,0,0,0.128],
                  '20210125':[0.056,0,0.043,0.062,0.16],
                  '20210213':[0.9,0.56,0.32,0.8,0],
                  '20210217':[0.7,0.99,0.008,0.23,0.56],
                  '20210219':[0.9,0.43,0.76,0.98,0.5])

预期输出:

In [2]: df
Out[2]: 
   A        B     c(Mean 20210111,..20210119 ) D(Mean of 20210120..20210129)..
0  81       21.8
1  80.09    22.04
2  83       21.8
3  85       21.7           
4  88       22.06

【问题讨论】:

可以做文字示例的时候尽量不要用图片。我们更容易复制和查看文本。另外,请在making a good pandas example 上阅读此问答 您构建数据框的代码无效。应该是DataFrame 而不是Dataframe,所有数组的长度必须相同,而目前不是。 @HenryEcker 纠正了它。请立即检查! 如果您想要每 10 天的平均值,您的预期输出的第一个示例应该是 20210111, ...20210119 【参考方案1】:

一种方法是将日期列与 DF 的其余部分隔离开来。转置它以能够使用正常的分组操作。然后转回并合并到 DataFrame 中未受影响的部分。

import pandas as pd

df = pd.DataFrame('A': [81, 80.09, 83, 85, 88],
                   'B': [21.8, 22.04, 21.8, 21.7, 22.06],
                   '20210113A.2': [0, 0.05, 0, 0, 0.433],
                   '20210122B.1': [0, 0.13, 0, 0, 0.128],
                   '20210125C.3': [0.056, 0, 0.043, 0.062, 0.16],
                   '20210213': [0.9, 0.56, 0.32, 0.8, 0],
                   '20210217': [0.7, 0.99, 0.008, 0.23, 0.56],
                   '20210219': [0.9, 0.43, 0.76, 0.98, 0.5])

# Unaffected Columns Go Here
keep_columns = ['A', 'B']

# Get All Affected Columns
new_df = df.loc[:, ~df.columns.isin(keep_columns)]

# Strip Extra Information From Column Names
new_df.columns = new_df.columns.map(lambda c: c[0:8])

# Transpose
new_df = new_df.T

# Convert index to DateTime for easy use
new_df.index = pd.to_datetime(new_df.index, format='%Y%m%d')

# Resample every 10 Days on new DT index (Drop any rows with no values)
new_df = new_df.resample("10D").mean().dropna(how='all')

# Transpose and Merge Back on DF
df = df[keep_columns].merge(new_df.T, left_index=True, right_index=True)

# For Display
print(df.to_string())

输出:

A B 2021-01-13 00:00:00 2021-01-23 00:00:00 2021-02-12 00:00:00 0 81.00 21.80 0.0000 0.056 0.833333 1 80.09 22.04 0.0900 0.000 0.660000 2 83.00 21.80 0.0000 0.043 0.362667 3 85.00 21.70 0.0000 0.062 0.670000 4 88.00 22.06 0.2805 0.160 0.353333
new_df = df.loc[:, ~df.columns.isin(keep_columns)]

new_df

0 1 2 3 4 20210113 0.000 0.05 0.000 0.000 0.433 20210122 0.000 0.13 0.000 0.000 0.128 20210125 0.056 0.00 0.043 0.062 0.160 20210213 0.900 0.56 0.320 0.800 0.000 20210217 0.700 0.99 0.008 0.230 0.560 20210219 0.900 0.43 0.760 0.980 0.500
new_df.index = pd.to_datetime(new_df.index, format='%Y%m%d')

new_df

0 1 2 3 4 2021-01-13 0.000 0.05 0.000 0.000 0.433 2021-01-22 0.000 0.13 0.000 0.000 0.128 2021-01-25 0.056 0.00 0.043 0.062 0.160 2021-02-13 0.900 0.56 0.320 0.800 0.000 2021-02-17 0.700 0.99 0.008 0.230 0.560 2021-02-19 0.900 0.43 0.760 0.980 0.500
new_df = new_df.resample("10D").mean().dropna(how='all')

new_df

0 1 2 3 4 2021-01-13 0.000000 0.09 0.000000 0.000 0.280500 2021-01-23 0.056000 0.00 0.043000 0.062 0.160000 2021-02-12 0.833333 0.66 0.362667 0.670 0.353333

new_df.T

2021-01-13 2021-01-23 2021-02-12 0 0.0000 0.056 0.833333 1 0.0900 0.000 0.660000 2 0.0000 0.043 0.362667 3 0.0000 0.062 0.670000 4 0.2805 0.160 0.353333

【讨论】:

如果有一些字符串连接到日期列(例如:20210113A.1、20210113B.1、20210123A.1),我们如何执行此操作 更新了我的答案以包含此内容。请尝试在您的问题中包含类似的相关信息。

以上是关于基于日期时间列名称的数据框的条件平均值的主要内容,如果未能解决你的问题,请参考以下文章

R - 基于日期列使用 group_by 的平均计算?

基于分子中特定条件的平均值

时间序列重采样错误 - 熊猫列中没有日期索引

如何验证数据框的日期列

pandas通过DatetimeProperties对象获取日期对象在所在周的周几星期几的名称信息(week name)并生成新的数据列计算不同星期名称下其它数据列的均值

过去 30 天的平均值,不包括当前记录(混合日期和基于行的条件)