Pandas - 如何遍历日期列表以过滤DataFrame

3 投票
2 回答
5746 浏览
提问于 2025-04-18 00:46

Pandas -- 如何通过日期列表来过滤一个数据表

我有一个名为 'numbers' 的数据表,长得像这样:

         Date   group    Number
0  2013-02-01  group1 -0.098765
1  2013-02-02  group2  0.519878
2  2013-02-03  group1 -0.098765
3  2013-02-04  group3  1.960784
4  2013-02-05  group3  2.859412
5  2013-02-06  group2  1.960784
6  2013-02-07  group1 -0.696594

还有一个包含日期的列表,存在另一个数据表 'datelist' 中,样子是这样的:

          Date
0    2013, 3,5
1    2013, 3,6
2    2013, 3,7
3    2013, 3,8
4    2013, 3,9
5   2013, 3,10
6   2013, 3,11

我想得到一个新的数据表,里面包含 'numbers' 中每一条记录,条件是日期要小于等于 datelist['Date']。

我试过这样做:

for date in datelist:
    end = datelist['Date'] 
    numbers2 = numbers[numbers.Date <= end] 

但是这个循环只返回了一个和原始数据表 'numbers' 一模一样的数据表。

         Date   group    Number
0  2013-02-01  group1 -0.098765
1  2013-02-02  group2  0.519878
2  2013-02-03  group1 -0.098765
3  2013-02-04  group3  1.960784
4  2013-02-05  group3  2.859412
5  2013-02-06  group2  1.960784
6  2013-02-07  group1 -0.696594

如果我手动输入一系列日期,我可以正确生成我需要的数据表,像这样:

end = pandas.datetime(2013,2,26) 
numbers2 = numbers[numbers.Date <= end] 

我不想把事情搞得太复杂,所以不详细说明后面的步骤——基本上,我是在 'numbers2' 数据表上按 'group' 进行分组,然后把计算结果添加到另一个数据表中,再继续处理下一个日期。

有没有人能告诉我,如何用循环来正确实现这个?

相关问题:

2 个回答

0

首先,我觉得 datelist 里可能包含的是元组之类的东西,而不是直接的日期。
在你确认 datelist 里包含的是日期时间对象之后,你可能想要用第二个数据框里的对应日期时间来过滤第一个数据框中的每一条记录。根据我所知道的,它们的大小应该是一样的。

numbers2 = numbers[numbers.Date <= datelist.Date]

你觉得这样行得通吗?

2

我不太确定我完全理解你的意思,但我觉得你是想从 number 这个数据框中,针对 datelist 中的每个日期,提取出一个子数据框。所以在你的例子中,你想创建7个数据框,对吧?

如果是这样的话,我会这样做:

首先,把 number 中的 date 列(我叫它 df)和 datelist 都转换成 datetime64 类型的列。我假设 number 中的日期列已经是 datetime64 类型了:

print df
        date   group  number   
0 2013-02-01  group1  -0.098765
1 2013-02-02  group2   0.519878
2 2013-02-03  group1  -0.098765
3 2013-02-04  group3   1.960784
4 2013-02-05  group3   2.859412
5 2013-02-06  group2   1.960784
6 2013-02-07  group1  -0.696594

然后,在 datelist 中,我会创建一个新的列,这个列也是 datetime64 类型(注意我修改了 datelist 中的日期,这样 number 数据框中的日期就不全都小于 datelist 中的日期了,而且我还减少了 datelist 的观察值,以便输出结果更小):

parse = lambda x: datetime(int(x[0]),int(x[1]),int(x[2]))
datelist['end'] = datelist['date'].str.split(',').apply(parse)
print datelist 

        date        end
0  2013, 2,3 2013-02-03
1  2013, 2,6 2013-02-06
2  2013, 3,6 2013-03-06
3  2013, 3,8 2013-03-08

现在,我会循环遍历 datelist 的每一行,每次都创建一个新的数据框,这个数据框是从那些满足 date <= end 的行中提取出来的:

pieces = []
for idx,rows in datelist[['end']].iterrows():
  x = df[df['date'] <= rows['end']]
  x['end'] = rows['end']
  pieces.append(x)

print pd.concat(pieces,ignore_index=True)

          date   group  number           end
0  2013-02-01  group1  -0.098765 2013-02-03
1  2013-02-02  group2   0.519878 2013-02-03
2  2013-02-03  group1  -0.098765 2013-02-03
3  2013-02-01  group1  -0.098765 2013-02-06
4  2013-02-02  group2   0.519878 2013-02-06
5  2013-02-03  group1  -0.098765 2013-02-06
6  2013-02-04  group3   1.960784 2013-02-06
7  2013-02-05  group3   2.859412 2013-02-06
8  2013-02-06  group2   1.960784 2013-02-06
9  2013-02-01  group1  -0.098765 2013-03-06
10 2013-02-02  group2   0.519878 2013-03-06
11 2013-02-03  group1  -0.098765 2013-03-06
12 2013-02-04  group3   1.960784 2013-03-06
13 2013-02-05  group3   2.859412 2013-03-06
14 2013-02-06  group2   1.960784 2013-03-06
15 2013-02-07  group1  -0.696594 2013-03-06
16 2013-02-01  group1  -0.098765 2013-03-08
17 2013-02-02  group2   0.519878 2013-03-08
18 2013-02-03  group1  -0.098765 2013-03-08
19 2013-02-04  group3   1.960784 2013-03-08
20 2013-02-05  group3   2.859412 2013-03-08
21 2013-02-06  group2   1.960784 2013-03-08
22 2013-02-07  group1  -0.696594 2013-03-08

我把这些数据框合并在一起了,但你也可以通过对 'end' 进行分组来处理它们。

撰写回答