首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在groupby之后,根据组中所有行的列值计算列中的值

在groupby之后,根据组中所有行的列值计算列中的值
EN

Stack Overflow用户
提问于 2019-12-24 20:03:29
回答 1查看 117关注 0票数 1

我正在寻找python中的以下功能:

我有一个熊猫DataFrame有4列: ID,StartDate,EndDate,Moment。

我想按ID分组,并评估组中的每一行Moment变量是否落在StartDate和EndDate之间的间隔之间。问题是我想为组中的每一行计算这个值。例如,在下面的DataFrame中,有两个组(ID=1和ID=2),两个组都包含5行。对于每一行,我希望两组中的每一行都有一个布尔值,无论该行中的moment变量是否落入组中的任何时间窗口,该窗口为date1,date2。

代码语言:javascript
运行
复制
import pandas as pd

i = pd.date_range('2018-04-11', periods=10, freq='2D20min')
i2 = pd.date_range('2018-04-12', periods=10, freq='2D20min')
i3 = pd.date_range('2018-04-9', periods=10, freq='1D6H')
id = ['1', '1', '1', '1', '1', '2', '2', '2', '2', '2']
ts = pd.DataFrame({'date1': i, 'date2': i2, 'moment': i3}, index=id)

ID  date1               date2               moment
1   2018-04-11 00:00:00 2018-04-12 00:00:00 2018-04-09 00:00:00
1   2018-04-13 00:20:00 2018-04-14 00:20:00 2018-04-10 06:00:00
1   2018-04-15 00:40:00 2018-04-16 00:40:00 2018-04-11 12:00:00
1   2018-04-17 01:00:00 2018-04-18 01:00:00 2018-04-12 18:00:00
1   2018-04-19 01:20:00 2018-04-20 01:20:00 2018-04-14 00:00:00
2   2018-04-21 01:40:00 2018-04-22 01:40:00 2018-04-15 06:00:00
2   2018-04-23 02:00:00 2018-04-24 02:00:00 2018-04-16 12:00:00
2   2018-04-25 02:20:00 2018-04-26 02:20:00 2018-04-17 18:00:00
2   2018-04-27 02:40:00 2018-04-28 02:40:00 2018-04-19 00:00:00
2   2018-04-29 03:00:00 2018-04-30 03:00:00 2018-04-20 06:00:00

在这种情况下,第一组第一行中的moment值不会落在五个时间间隔中的任何一个时间间隔内。第二个也不是。第三个值2018-04-11 12:00:00确实落在第一行的间隔内,因此我希望返回True

期望的结果如下所示:

代码语言:javascript
运行
复制
ID  date1               date2               moment              result
1   2018-04-11 00:00:00 2018-04-12 00:00:00 2018-04-09 00:00:00 False
1   2018-04-13 00:20:00 2018-04-14 00:20:00 2018-04-10 06:00:00 False
1   2018-04-15 00:40:00 2018-04-16 00:40:00 2018-04-11 12:00:00 True
1   2018-04-17 01:00:00 2018-04-18 01:00:00 2018-04-12 18:00:00 False
1   2018-04-19 01:20:00 2018-04-20 01:20:00 2018-04-14 00:00:00 True
2   2018-04-21 01:40:00 2018-04-22 01:40:00 2018-04-15 06:00:00 False
2   2018-04-23 02:00:00 2018-04-24 02:00:00 2018-04-16 12:00:00 False
2   2018-04-25 02:20:00 2018-04-26 02:20:00 2018-04-17 18:00:00 False
2   2018-04-27 02:40:00 2018-04-28 02:40:00 2018-04-19 00:00:00 False
2   2018-04-29 03:00:00 2018-04-30 03:00:00 2018-04-20 06:00:00 False

编辑

我已经用下面的方法“解决”了这个问题,但我正在寻找一种更pythonic的,也许更快的方法……

代码语言:javascript
运行
复制
boolean_result = []
for c in ts.index.unique():
    temp = ts.loc[ts.index == c]
    for row in temp.index:
        current_date = temp['moment'][row]
        boolean_result.append(max((temp['date1'] <= current_date)
                                  & (current_date <= temp['date2'])))
ts['Result'] = boolean_result
EN

回答 1

Stack Overflow用户

发布于 2019-12-24 21:16:50

如果您的数据帧太大,这实际上可能会非常慢,并且可能存在除以下解决方案之外的最佳解决方案:

代码语言:javascript
运行
复制
def time_in_range(start, end, x):
    """Return true if x is in the range [start, end]"""
    if start <= x and x <= end:
        return True
    else:
        return False

# empty list to be appended
result = []
test_list = []

for i in ts.index.unique():

    temp_df = ts[ts.index == i]

    for j in range(0, len(temp_df)):
        for k in range(0, len(temp_df)):    
            test_list.append(time_in_range(temp_df.date1.iloc[k], temp_df.date2.iloc[k], temp_df.moment.iloc[j]))

        result.append(any(test_list))
        # reset the list
        test_list = []

ts['result'] = result
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59468571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档