【问题标题】:Python - Split same day (date) into multiple coulmnsPython - 将同一天(日期)拆分为多列
【发布时间】:2022-10-04 17:17:21
【问题描述】:

我正在使用熊猫,我有一列出勤时间戳数据(日期)。 我想将同一天的值拆分为 (InTime) 和 (OutTime) 列。

df = df[['Date']]

Date
Thu 1/09 9:10 AM
Thu 1/09 6:10 PM
Fri 2/09 9:04 AM
Fri 2/09 6:02 PM

我正在努力实现以下结果。

In Time            OutTime
Thu 1/09 9:10 AM   Thu 1/09 6:10 PM 
Fri 2/09 9:04 AM   Fri 2/09 6:02 PM

谢谢。

编辑

谢谢您的帮助。问题是数据没有应有的整洁。缺少 In-Time/Out-Time 或几乎重复的记录。 + 我是一个基本的 python 用户而且我什至无法理解根据我的要求修改它的代码。

我要求查看完整的场景以及到目前为止我为达到预期结果所做的尝试。

这是一个考勤机数据,用户要么忘记标记出勤,要么机器创建了重复条目以获得更长的拇指印象。因此,所提供的代码在发现任何重复或缺失记录的任何地方都会混淆 AM 和 PM 列。

示例数据如下所示

User    Date
11  Thu 1/09 9:10 AM
3   Thu 1/09 9:10 AM
4   Thu 1/09 9:10 AM
2   Thu 1/09 9:23 AM
5   Thu 1/09 9:39 AM    
... ...   ...

12  Fri 30/09 5:55 PM
5   Fri 30/09 6:01 PM
6   Fri 30/09 6:04 PM
11  Fri 30/09 6:09 PM

我正在尝试为 In 和 Out 时间戳位于不同列中的每个用户创建多个 .csv 文件包括非连续天数的空记录因此可以将其粘贴到已经创建的 excel 模板中。

df = pd.read_csv('input.csv', encoding="utf-8", sep=',')
df = df[["User", "Date"]]
dataframe = pd.DataFrame(df,
                         columns=['User', 'Date'])
users = {
    'falcon': 2,
    'charlie': 3,
}

for username, ID in users.items():
    df = dataframe.loc[dataframe['User'] == ID]
    df = df[['Date']]
    df.to_csv(username + ".csv", encoding="utf-8", sep=',', header=False, index=False)

结果

Thu 1/09 9:10 AM
Thu 1/09 6:11 PM
Fri 2/09 9:18 AM    //Missing PM
Sat 3/09 10:44 AM
Sat 3/09 6:00 PM
Mon 5/09 9:22 AM    //Missing PM
Tue 6/09 9:09 AM
Tue 6/09 6:25 PM
Wed 7/09 9:18 AM
Wed 7/09 6:33 PM

我试着拆分这些日期,以便带有 AM / PM 的条目在其尊重的列中分开(包括缺失日期的空记录).

【问题讨论】:

    标签: python pandas csv date split


    【解决方案1】:

    这是 pandas.DataFrame.joinpandas.DataFrame.shift 的解决方案:

    new_df = (
                df.add_suffix('_In_time')
                  .join(df.shift(-1).add_suffix('_Out_time'))
                  .iloc[::2]
             )
    

    # 输出 :

    print(new_df)
    
           Date_In_time     Date_Out_time
    0  Thu 1/09 9:10 AM  Thu 1/09 6:10 PM
    1  Fri 2/09 9:04 AM  Fri 2/09 6:02 AM
    

    【讨论】:

    • 非常感谢。差不多好了。数据有 AM 和 PM 值的缺失或重复条目。如果我们可以为缺失的值插入空白值。事实上,我也需要非连续天的空格。
    【解决方案2】:

    另一种方法,将列转换为日期时间并使用它。尝试:

    df
        Date
    0   Thu 1/09 9:10 AM
    1   Thu 1/09 6:10 PM
    2   Fri 2/09 9:04 AM
    3   Fri 2/09 6:02 PM
    
    df['Date'] = pd.to_datetime(df['Date'] + ' 2022', format='%a %d/%m %H:%M %p %Y')
    df['day'] = df['Date'].dt.date
    df['time'] = df['Date'].dt.time
    
    df.groupby('day').agg(InTime=('time', 'first'), OutTime=('time', 'last')).reset_index()
    
        day         InTime      OutTime
    0   2022-09-01  09:10:00    06:10:00
    1   2022-09-02  09:04:00    06:02:00
    
    

    【讨论】:

    • 谢谢,但我需要的结果需要相同的日期格式。也许在代码之后重新格式化它可能会产生所需的结果。
    • 我将在我的答案中添加日期时间格式解决方案,您需要什么日期格式?
    • 谢谢。任何可以被 excel 轻松识别的日期/时间格式。 (22 年 9 月 30 日上午 9:05)应该可以正常工作。
    【解决方案3】:

    一个可能的解决方案,基于pandas.DataFrame.pivot

    # separate day from time
    df[['Date1', 'Date2']] = df['Date'].str.split('(?<=d)s(?=d)', expand=True)
    
    # create column with colnames for the new columns to be created by pivot
    df['names'] = ['inTime', 'OutTime'] * (len(df)//2)
    (df.pivot(index='Date1', columns='names', values='Date')
     .reset_index(drop=True).iloc[:,::-1])
    

    输出:

    names            inTime           OutTime
    0      Fri 2/09 9:04 AM  Fri 2/09 6:02 PM
    1      Thu 1/09 9:10 AM  Thu 1/09 6:10 PM
    

    如果数据集没有时间从早到晚排序,则解决方案可能如下:

    # separate day from time
    df[['Date1', 'Date2', 'Date3']] = df['Date'].str.split(
        '(?<=d)s(?=d)|s(?=.M$)', expand=True)
    
    # this is needed if the times are no sorted in the initial dataset
    df = df.sort_values(['Date1', 'Date3', 'Date2'])
    
    # create column with colnames for the new columns to be created by pivot
    df['names'] = ['inTime', 'OutTime'] * (len(df)//2)
    (df.pivot(index='Date1', columns='names', values='Date')
     .reset_index(drop=True).iloc[:,::-1])
    

    完整代码:

    import pandas as pd
    import numpy as np
    from io import StringIO
    
    text = """
    Date
    Thu 1/09 9:10 AM
    Thu 1/09 6:10 PM
    Fri 2/09 9:04 AM
    Fri 2/09 6:02 PM
    """
    
    df = pd.read_csv(StringIO(text), sep='s{2,}', engine='python')
    
    # separate day from time
    df[['Date1', 'Date2']] = df['Date'].str.split('(?<=d)s(?=d)', expand=True)
    
    # create column with colnames for the new columns to be created by pivot
    df['names'] = ['inTime', 'OutTime'] * (len(df)//2)
    (df.pivot(index='Date1', columns='names', values='Date')
     .reset_index(drop=True).iloc[:,::-1])
    

    【讨论】:

    • 嗨@PaulS,很高兴在这里见到你使用 Python。不错的正则表达式方法!
    • 我记得你是来自 R StackOverflow 的好人!现在,我正在尝试学习 Python。
    • 也谢谢你!我也在尝试学习更多的 Python。我肯定会从你的好答案中学到很多东西!
    • 感谢您抽出宝贵时间,但由于某种原因,您的代码无法正常工作 + 我也无法理解。 (正则表达式对我来说总是很困难,双斜杠到底是什么?//我们将它用于某些语言的 cmets :D
    • @NaveedAbbas:在您编辑之前,我的代码可以很好地解决您的初始问题-您的问题现在是不同的问题! Python 中的双斜线表示整数除法:Python Double Slash
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 2019-02-20
    • 1970-01-01
    • 2021-12-17
    • 2021-01-26
    相关资源
    最近更新 更多