如何根据另一列中的日期值范围创建排名列?

问题描述

data = [
    ["Item_1","2020-06-01"],["Item_1","2020-06-02"],"2020-05-27"],["Item_2","2018-04-15"],"2018-04-18"],"2018-04-22"],"2018-04-28"],]

df = pd.DataFrame(data,columns=["Item_ID","Dates"])
df

我有一个包含 Item IDsDates 列的数据集。我想在新列中分配排序的“排名”,其中排名/顺序值增加 IF一个日期是前一个日期的 >3 天,否则它保持不变。

因此所需的输出如下所示:

    Item_ID    Dates    Date Order
    Item_1  2020-05-27      1
    Item_1  2020-06-01      2
    Item_1  2020-06-02      2 
    Item_2  2018-04-15      1
    Item_2  2018-04-18      1
    Item_2  2018-04-22      2 
    Item_2  2018-04-28      3

解决方法

我们可以使用 groupby apply 来计算每组天之间的差异,然后使用 cumsum 来“计算”有多少差异大于 (`gt) 3 天:

# Convert to datetime (if not already)
df['Dates'] = pd.to_datetime(df['Dates'])
# Sort in correct order
df = df.sort_values(['Item_ID','Dates'],ignore_index=True)
# Calculate Ranking per Group
df['Date Order'] = (
    df.groupby('Item_ID')['Dates'].apply(
        lambda s: s.diff().gt(pd.Timedelta(days=3)).cumsum() + 1
    )
)

也可以 groupby 两次并使用 groupby diffgroupby cumsum

# Convert to datetime (if not already)
df['Dates'] = pd.to_datetime(df['Dates'])
# Sort in correct order
df = df.sort_values(['Item_ID',ignore_index=True)

# Reuse same Grouper
g = df.groupby('Item_ID') 
# Calculate Difference per group and compare (whole Series)
df['Date Order'] = g['Dates'].diff().gt(pd.Timedelta(days=3))
# Calculate cumsum per group
df['Date Order'] = g['Date Order'].cumsum() + 1

两者都产生df

  Item_ID      Dates  Date Order
0  Item_1 2020-05-27           1
1  Item_1 2020-06-01           2
2  Item_1 2020-06-02           2
3  Item_2 2018-04-15           1
4  Item_2 2018-04-18           1
5  Item_2 2018-04-22           2
6  Item_2 2018-04-28           3

以下是作为 DataFrame 的每组步骤的细分:

s = pd.Series([pd.Timestamp('2020-05-27 00:00:00'),pd.Timestamp('2020-06-01 00:00:00'),pd.Timestamp('2020-06-02 00:00:00')],name='Dates',index=pd.Series({0: 'Item_1',1: 'Item_1',2: 'Item_1'},name='Item_ID'))
steps_per_group = pd.DataFrame({
    'diff': s.diff(),'gt': s.diff().gt(pd.Timedelta(days=3)),'cumsum': s.diff().gt(pd.Timedelta(days=3)).cumsum(),'cumsum 1 start': s.diff().gt(pd.Timedelta(days=3)).cumsum() + 1
})
          diff     gt  cumsum  cumsum 1 start
Item_ID                                      
Item_1     NaT  False       0               1
Item_1  5 days   True       1               2
Item_1  1 days  False       1               2
,

来自您的DataFrame

>>> import pandas as pd

>>> data = [
...     ["Item_1","2020-05-27"],...     ["Item_1","2020-06-01"],"2020-06-02"],...     ["Item_2","2018-04-15"],"2018-04-18"],"2018-04-22"],"2018-04-28"],... ]
>>> df = pd.DataFrame(data,columns=["Item_ID","Dates"])
>>> df['Dates'] = pd.to_datetime(df['Dates'],format="%Y-%m-%d")
>>> df
    Item_ID     Dates
0   Item_1  2020-05-27
1   Item_1  2020-06-01
2   Item_1  2020-06-02
3   Item_2  2018-04-15
4   Item_2  2018-04-18
5   Item_2  2018-04-22
6   Item_2  2018-04-28

我们可以像这样获取按 diff 分组的日期 Item_ID

>>> window_size = 3
>>> df['diff'] = df.groupby('Item_ID')["Dates"].diff().dt.days.gt(window_size)
>>> df
    Item_ID     Dates   diff
0   Item_1  2020-05-27  False
1   Item_1  2020-06-01  True
2   Item_1  2020-06-02  False
3   Item_2  2018-04-15  False
4   Item_2  2018-04-18  False
5   Item_2  2018-04-22  True
6   Item_2  2018-04-28  True

然后,通过再次按 Item_ID 分组并应用 cumsum,我们得到了预期的结果:

>>> df['Date Order'] = df.groupby('Item_ID')["diff"].cumsum()+1
>>> df
    Item_ID     Dates   diff    Date Order
0   Item_1  2020-05-27  False   1
1   Item_1  2020-06-01  True    2
2   Item_1  2020-06-02  False   2
3   Item_2  2018-04-15  False   1
4   Item_2  2018-04-18  False   1
5   Item_2  2018-04-22  True    2
6   Item_2  2018-04-28  True    3

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...