首页 > 解决方案 > 如何比较工作人员时间范围内的事务时间点以将员工添加到熊猫的事务表中?

问题描述

我想计算工人小费。每笔交易都有几名工人工作。我有 2 个数据框,ts_df(用于交易)和 shift_df(用于工人轮班),用于计算每个工作的小费金额。

事务表示例:

>>> ts_df.head()
         Date      Time   tip
1  2021-03-01  09:00:39  2.40
2  2021-03-01  09:27:39  5.45
4  2021-03-01  09:54:50  2.00
5  2021-03-01  09:57:37  2.10
6  2021-03-01  10:35:56  2.57
>>> ts_df.dtypes
Date     object
Time     object
tip     float64
dtype: object

以下是班次交易的示例:

>>> shift_df.head()
         Date Clock_start Clock_end       employee
0  2021-03-01    08:30:00  14:30:00           Jose
1  2021-03-01    09:30:00  15:30:00          April
2  2021-03-02    06:00:00  07:30:00           John
3  2021-03-02    08:30:00  14:30:00           Jose
4  2021-03-02    09:30:00  15:30:00          April
>>> shift_df.dtypes
Date           object
Clock_start    object
Clock_end      object
employee       object
dtype: object

所有日期和时间对象都是 python date() 和 time() 对象。

例如,Jose 和 April 参与了交易 [4] (4 2021-03-01 09:54:50 2.00)。Jose 和 April 应该各得到 1.00。最好的方法是什么?

我正在考虑的是,可以将交易的工作人员列表添加到列表中以计算小费金额。像这样的东西:

在 ts_df 中:

         Date      Time   tip      workers
1  2021-03-01  09:00:39  2.40      ['Jose']
2  2021-03-01  09:27:39  5.45      ['Jose']
4  2021-03-01  09:54:50  2.00      ['Jose', 'April']
5  2021-03-01  09:57:37  2.10      ['Jose', 'April']
6  2021-03-01  10:35:56  2.57      ['Jose', 'April']

请教我如何比较两个独立的表格来计算工人的小费。

提前致谢!

标签: pythonpandas

解决方案


重现原始数据框:

ts_df = pd.DataFrame(
    [
     ['2021-03-01', '09:00:39', 2.4],
     ['2021-03-01', '09:27:39', 5.45],
     ['2021-03-01', '09:54:50', 2.0],
     ['2021-03-01', '09:57:37', 2.1],
     ['2021-03-01', '10:35:36', 2.57]
    ]
)
ts_df.columns=['Date', 'Time', 'tip']

shift_df = pd.DataFrame(
    [
     ['2021-03-01', '08:30:00', '14:30:00', 'Jose'],
     ['2021-03-01', '09:30:00', '15:30:00', 'April'],
     ['2021-03-02', '06:00:00', '07:30:00', 'John'],
     ['2021-03-02', '08:30:00', '14:30:00', 'Jose'],
     ['2021-03-02', '09:30:00', '15:30:00', 'April']
    ]
)

shift_df.columns = ['Date', 'Clock_start', 'Clock_end', 'employee']

ts_df['Date'] = pd.to_datetime(ts_df['Date']).dt.date
ts_df['Time'] = pd.to_datetime(ts_df['Time'], format = '%H:%M:%S').dt.time

shift_df['Date'] = pd.to_datetime(shift_df['Date']).dt.date
shift_df['Clock_start'] = (
    pd.to_datetime(shift_df['Clock_start'], format = '%H:%M:%S').dt.time
)
shift_df['Clock_end'] = (
    pd.to_datetime(shift_df['Clock_end'], format = '%H:%M:%S').dt.time
)

现在我们需要像@Miguel 说的那样交叉加入和过滤!

temp_df = ts_df.merge(
    shift_df
)

ts_df = (
    temp_df.loc[
        (temp_df.Clock_start <= temp_df.Time) &
        (temp_df.Time <= temp_df.Clock_end)
    ]
)

交叉连接

现在很酷,我们有每个工人实例和他们得到的小费,但我们仍然没有您想要的列表,每个小费只有一行

ts_df = (
    ts_df
    .groupby(['Date', 'Time', 'tip'])['employee']
    .apply(list)
    .reset_index(name='workers')
)

工人名单


推荐阅读