Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在pandas中通过值滚动窗口执行排除组中的当前日期?_Python_Pandas_Dataframe - Fatal编程技术网

Python 如何在pandas中通过值滚动窗口执行排除组中的当前日期?

Python 如何在pandas中通过值滚动窗口执行排除组中的当前日期?,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个包含ID、日期和数值的数据框。我将每个ID的数据分组,然后计算前几行的累积量,时间窗口为30天。在下面的数据框中,这是使用下面的代码完成的(实际的数据框包含多个ID和多个日期) 因此,简而言之,列SUM_AMOUNT是基于其他列创建的 代码: 数据帧: ID DATE AMOUNT SUM_AMOUNT 111935 100000 2015-02-18 455.00

我有一个包含ID、日期和数值的数据框。我将每个ID的数据分组,然后计算前几行的累积量,时间窗口为30天。在下面的数据框中,这是使用下面的代码完成的(实际的数据框包含多个ID和多个日期)

因此,简而言之,列SUM_AMOUNT是基于其他列创建的

代码:

数据帧:

         ID       DATE                  AMOUNT                SUM_AMOUNT
111935   100000   2015-02-18            455.00                    NaN
111936   100000   2015-02-18            455.00                 455.00
111937   100000   2015-04-02            455.00                    NaN
111938   100000   2015-04-02            925.00                 455.00
111939   100000   2015-04-02           2780.00                1380.00
111940   100000   2015-04-09            895.00                4160.00
111941   100000   2015-04-09            425.00                5055.00
111942   100000   2015-04-09            425.00                5480.00
111943   100000   2015-04-09            925.00                5905.00
111944   100000   2015-04-09            455.00                6830.00
111947   100000   2015-05-21           1003.00                    NaN
111945   100000   2015-05-26            455.00                1003.00
111946   100000   2015-05-26            925.00                1458.00
111948   100000   2015-05-26            455.00                2383.00
111949   100000   2015-05-26           2780.00                2838.00
111950   100000   2015-05-26            425.00                5618.00
111951   100000   2015-05-26           1000.00                6043.00
111952   100000   2015-05-26            455.00                7043.00
111953   100000   2015-05-26            455.00                7498.00
111954   100000   2015-06-19            925.00                7953.00
111955   100000   2015-06-19           1820.00                8878.00
111956   100000   2015-06-19            925.00               10698.00
如您所见,每个ID都有具有相同日期的行。我无法得到更详细的日期。我不想在计算中考虑相同日期的值,因为如果它们在同一日期,并且顺序很重要,我不知道它们的顺序是什么

我真正想要的

我希望能够获得过去30天内所有数据点的累计总和,不包括当前行的日期。 我已更改数据框以反映我想要的:

         ID       DATE                  AMOUNT                SUM_AMOUNT
111935   100000   2015-02-18            455.00                    NaN
111936   100000   2015-02-18            455.00                    NaN
111937   100000   2015-04-02            455.00                    NaN
111938   100000   2015-04-02            925.00                    NaN
111939   100000   2015-04-02           2780.00                    NaN
111940   100000   2015-04-09            895.00                4160.00
111941   100000   2015-04-09            425.00                4160.00
111942   100000   2015-04-09            425.00                4160.00
111943   100000   2015-04-09            925.00                4160.00
111944   100000   2015-04-09            455.00                4160.00
111947   100000   2015-05-21           1003.00                    NaN
111945   100000   2015-05-26            455.00                1003.00
111946   100000   2015-05-26            925.00                1003.00
111948   100000   2015-05-26            455.00                1003.00
111949   100000   2015-05-26           2780.00                1003.00
111950   100000   2015-05-26            425.00                1003.00
111951   100000   2015-05-26           1000.00                1003.00
111952   100000   2015-05-26            455.00                1003.00
111953   100000   2015-05-26            455.00                1003.00
111954   100000   2015-06-19            925.00                7953.00
111955   100000   2015-06-19           1820.00                7953.00
111956   100000   2015-06-19            925.00                7953.00
因此,如果行的日期为2015-06-19,我希望在30天的窗口中包含所有先前行的总和,但日期为2015-06-19的行不应包含在该窗口中

另一个需要提及的重要事项是,我不能将行折叠成每个ID和日期一行


如何执行此操作?

您可以迭代df的行,并每次定义一个新掩码:

df = pd.DataFrame({'Date' : ["2015-02-18", "2015-02-18", "2015-04-02", "2015-04-02", "2015-04-02", "2015-04-09"],
                  'Amount' : [455, 455, 455, 925, 2780, 895]})
  Date  Amount
0  2015-02-18     455
1  2015-02-18     455
2  2015-04-02     455
3  2015-04-02     925
4  2015-04-02    2780
5  2015-04-09     895

# We make sure our type is date
df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m-%d')

for index, row in df.iterrows():
    # We look on previous rows with dates within 30 days of our own
    mask = (df['Date'] <= row['Date']) & (df['Date'] >= row['Date'] - timedelta(days=30)) & (df.index<index)
    df.loc[index, 'sum'] = df.loc[mask,'Amount'].sum()
在您的预期产出中,您在合计金额时,不一致地采用或忽略同一天。我包含了它们,但您可以通过将遮罩更改为:

# There is no need for the index condition either so we remove it
mask = (df['Date'] >= row['Date'] - timedelta(days=30))

由于同一天有多个值,我想说的是,您应该首先每天获取
总和
,然后在日期之前的最后30个值上使用to not include today。使用
groupby
对每个ID执行这些操作,然后在
df
中对ID和日期执行这些操作

df = df.merge( (df.groupby('ID').resample('1D', on='DATE').sum()['AMOUNT'].shift()
                  .rolling(30, min_periods=1).sum().fillna(0).reset_index()), 
               on = ['ID', 'DATE'], how='left', suffixes=('', '_SUM'))
您可以得到
df
,例如:

        DATE      ID  AMOUNT  AMOUNT_SUM
0  2015-02-18  100000   455.0         0.0
1  2015-02-18  100000   455.0         0.0
2  2015-04-02  100000   455.0         0.0
3  2015-04-02  100000   925.0         0.0
4  2015-04-02  100000  2780.0         0.0
5  2015-04-09  100000   895.0      4160.0
6  2015-04-09  100000   425.0      4160.0
7  2015-04-09  100000   425.0      4160.0
8  2015-04-09  100000   925.0      4160.0
9  2015-04-09  100000   455.0      4160.0
10 2015-05-21  100000  1003.0         0.0
11 2015-05-26  100000   455.0      1003.0
12 2015-05-26  100000   925.0      1003.0
13 2015-05-26  100000   455.0      1003.0
14 2015-05-26  100000  2780.0      1003.0
15 2015-05-26  100000   425.0      1003.0
16 2015-05-26  100000  1000.0      1003.0
17 2015-05-26  100000   455.0      1003.0
18 2015-05-26  100000   455.0      1003.0
19 2015-06-19  100000   925.0      7953.0
20 2015-06-19  100000  1820.0      7953.0
21 2015-06-19  100000   925.0      7953.0

你能利用一下吗<代码>。。。我不能将行折叠为每个ID和日期一行。-为什么?IIUC,索引为111938和111937的行应该是
NaN
,不是吗?@Ben.T你说得对,已经修复了这个问题。@wwii为了将来的处理,我需要将每一行分开。谢谢,这是我需要的开箱即用的想法。工作起来很有魅力。
df = df.merge( (df.groupby('ID').resample('1D', on='DATE').sum()['AMOUNT'].shift()
                  .rolling(30, min_periods=1).sum().fillna(0).reset_index()), 
               on = ['ID', 'DATE'], how='left', suffixes=('', '_SUM'))
        DATE      ID  AMOUNT  AMOUNT_SUM
0  2015-02-18  100000   455.0         0.0
1  2015-02-18  100000   455.0         0.0
2  2015-04-02  100000   455.0         0.0
3  2015-04-02  100000   925.0         0.0
4  2015-04-02  100000  2780.0         0.0
5  2015-04-09  100000   895.0      4160.0
6  2015-04-09  100000   425.0      4160.0
7  2015-04-09  100000   425.0      4160.0
8  2015-04-09  100000   925.0      4160.0
9  2015-04-09  100000   455.0      4160.0
10 2015-05-21  100000  1003.0         0.0
11 2015-05-26  100000   455.0      1003.0
12 2015-05-26  100000   925.0      1003.0
13 2015-05-26  100000   455.0      1003.0
14 2015-05-26  100000  2780.0      1003.0
15 2015-05-26  100000   425.0      1003.0
16 2015-05-26  100000  1000.0      1003.0
17 2015-05-26  100000   455.0      1003.0
18 2015-05-26  100000   455.0      1003.0
19 2015-06-19  100000   925.0      7953.0
20 2015-06-19  100000  1820.0      7953.0
21 2015-06-19  100000   925.0      7953.0