如何在Pandas DataFrame中按日期列遍历并调用自定义函数?
如何按日期分组遍历Pandas DataFrame并调用自定义函数计算
我最近在处理Pandas DataFrame时遇到了个小问题:我想针对日期列里的每个日期,把该日期对应的x、y、z值传入自定义函数计算,但不确定怎么正确调用函数。我写了一段代码,但好像不对,想请大家帮忙看看。
现有代码
import pandas as pd def calc_funct(x, y, z): func = x*y*z return func if __name__ == '__main__': df = pd.read_csv('C:/Data.csv') for column in df: results = calc_funct(df['x'], df['y'], df['z']) print(result)
输入数据示例
| date | x | y | z | |
|---|---|---|---|---|
| 0 | 2017-11-11 | 18 | 17 | 7 |
| 1 | 2017-11-11 | 16 | 19 | 3 |
| 2 | 2017-11-11 | 13 | 14 | 2 |
| 3 | 2017-11-11 | 12 | 13 | 1 |
| 4 | 2017-11-11 | 11 | 12 | 9 |
| 5 | 2017-11-11 | 10 | 11 | 10 |
| 6 | 2017-11-11 | 21 | 10 | 11 |
| 7 | 2017-11-12 | 13 | 19 | 12 |
| 8 | 2017-11-13 | 18 | 17 | 12 |
| 9 | 2017-11-14 | 9 | 10 | 20 |
| 10 | 2017-11-15 | 2 | 20 | 13 |
| 11 | 2017-11-18 | 13 | 13 | 9 |
| 12 | 2017-11-19 | 18 | 14 | 16 |
| 13 | 2017-11-20 | 14 | 11 | 19 |
| 14 | 2017-11-21 | 18 | 15 | 19 |
期望实现
针对每个日期(如2017-11-11),对该日期下的x、y、z值进行计算(如加减等操作)并存储到列表中,再依次处理后续日期。
问题分析
先说说你现有代码里的几个小问题:
- 循环
for column in df是在遍历DataFrame的列名,而不是按日期分组,完全不符合你的需求; - 调用
calc_funct(df['x'], df['y'], df['z'])时,传入的是整个x、y、z列,Pandas会做元素级运算,返回整列的乘积结果,而不是按日期分组的每行计算; - 最后打印的
result是未定义的变量,应该是results。
解决方案
这里给你两种实用的实现方式,根据你的需求选择:
方式一:手动遍历日期分组,单独存储每个日期的结果
这种方式更直观,适合需要对每个日期的结果做单独处理(比如单独保存、分析)的场景:
import pandas as pd def calc_funct(x, y, z): # 这里可以替换成你需要的任意计算逻辑,比如加减组合等 return x * y * z if __name__ == '__main__': df = pd.read_csv('C:/Data.csv') # 按date列分组,把相同日期的行归为一组 date_groups = df.groupby('date') # 用字典存储每个日期的计算结果,键是日期,值是该日期下所有行的计算结果列表 date_results = {} # 遍历每个日期分组 for date, group_data in date_groups: # 取出当前日期分组的x、y、z值,用zip配对每行的三个值 row_values = zip(group_data['x'], group_data['y'], group_data['z']) # 对每行应用自定义函数,生成结果列表 current_results = [calc_funct(x, y, z) for x, y, z in row_values] # 存入字典 date_results[date] = current_results # 打印当前日期的结果 print(f"日期 {date} 的计算结果:{current_results}") # 如果需要把计算结果合并回原DataFrame,可以用下面这行 df['calculated_value'] = df.apply(lambda row: calc_funct(row['x'], row['y'], row['z']), axis=1) print("\n添加计算结果后的完整DataFrame:") print(df)
方式二:用groupby+apply直接处理分组,合并结果到原DataFrame
这种方式更简洁,适合直接把计算结果附加到原DataFrame的场景:
import pandas as pd def calc_funct(x, y, z): return x * y * z # 定义处理单个日期分组的函数 def process_single_date(group): # 对分组内的每一行应用计算函数 group['calculated_value'] = group.apply(lambda row: calc_funct(row['x'], row['y'], row['z']), axis=1) return group if __name__ == '__main__': df = pd.read_csv('C:/Data.csv') # 按日期分组并应用处理函数,得到带结果的DataFrame result_df = df.groupby('date').apply(process_single_date) # 查看结果 print(result_df) # 如果需要单独查看某个日期的结果 target_date = '2017-11-11' print(f"\n{target_date} 的详细计算结果:") print(result_df[result_df['date'] == target_date][['x', 'y', 'z', 'calculated_value']])
关键说明
groupby('date')是核心:它会自动把DataFrame中相同日期的行聚合成一个子DataFrame,让你可以单独处理每个日期的数据;- 自定义函数的灵活性:你可以随时修改
calc_funct里的逻辑,比如改成x + y - z或者其他复杂计算,两种实现方式都能适配; - 如果你的计算是元素级的简单运算,甚至可以不用自定义函数,直接用Pandas的向量运算,比如
df['calculated_value'] = df['x'] * df['y'] * df['z'],效率更高。
内容的提问来源于stack exchange,提问作者MCM
相关产品推荐
相关产品推荐

