如何将groupby()与between_time()一起使用



我有一个DataFrame,希望将某一天的列a中的所有值与当天6点的a的值相乘。如果没有6时00分的输入,则当天应保持不变。

不幸的是,下面的代码给出了一个错误。

我必须如何更正此代码/用任何有效的解决方案替换它?

import pandas as pd
import numpy as np
start = pd.Timestamp('2000-01-01')
end = pd.Timestamp('2000-01-03')
t = np.linspace(start.value, end.value, 9)
datetime1 = pd.to_datetime(t)
df = pd.DataFrame( {'a':[1,3,4,5,6,7,8,9,14]})
df['date']= datetime1
print(df)
def myF(x):
y = x.set_index('date').between_time('05:59', '06:01').a
return y

toMultiplyWith =  df.groupby(df.date.dt.floor('D')).transform(myF)

a                date
0   1 2000-01-01 00:00:00
1   3 2000-01-01 06:00:00
2   4 2000-01-01 12:00:00
3   5 2000-01-01 18:00:00
4   6 2000-01-02 00:00:00
5   7 2000-01-02 06:00:00
6   8 2000-01-02 12:00:00
7   9 2000-01-02 18:00:00
8  14 2000-01-03 00:00:00
....
AttributeError: ("'Series' object has no attribute 'set_index'", 'occurred at index a')

您应该更改这一行:

toMultiplyWith = df.groupby(df.date.dt.floor('D')).transform(myF)

到此:

toMultiplyWith = df.groupby(df.date.dt.floor('D')).apply(myF)

使用.apply而不是.transform将得到所需的结果。

apply是正确的选择,因为它隐式地将每个组的所有列作为DataFrame传递给自定义函数。

要了解更多关于这两种方法之间的区别,请考虑以下答案

如果你坚持使用between_times(...)函数,那就是方法:

df = df.set_index('date') 
mask = df.between_time('05:59', '06:01').index
df.loc[mask, 'a'] = df.loc[mask, 'a'] ** 2 # the operation you want to perform
df.reset_index(inplace=True)

输出:

date   a
0 2000-01-01 00:00:00   1
1 2000-01-01 06:00:00   9
2 2000-01-01 12:00:00   4
3 2000-01-01 18:00:00   5
4 2000-01-02 00:00:00   6
5 2000-01-02 06:00:00  49
6 2000-01-02 12:00:00   8
7 2000-01-02 18:00:00   9
8 2000-01-03 00:00:00  14

如果我实现了您的目标,您可以使用apply返回与原始数据帧(模拟transform(具有相同行数的数据帧:

def myF(grp):
time = grp.date.dt.strftime('%T')
target_idx = time == '06:00:00'
if target_idx.any():
grp.loc[~target_idx, 'a_sum'] = grp.loc[~target_idx, 'a'].values * grp.loc[target_idx, 'a'].values
else:
grp.loc[~target_idx, 'a_sum'] = np.nan
return grp
df.groupby(df.date.dt.floor('D')).apply(myF)

输出:

a                date  a_sum
0   1 2000-01-01 00:00:00    3.0
1   3 2000-01-01 06:00:00    NaN
2   4 2000-01-01 12:00:00   12.0
3   5 2000-01-01 18:00:00   15.0
4   6 2000-01-02 00:00:00   42.0
5   7 2000-01-02 06:00:00    NaN
6   8 2000-01-02 12:00:00   56.0
7   9 2000-01-02 18:00:00   63.0
8  14 2000-01-03 00:00:00    NaN

请注意,对于每一天,时间不是06:00:00的每个值都乘以时间等于06:00:000的值。它为06:00:00值本身以及没有此时间的组重新运行NaN

最新更新