Python Pandas检查字符串是否只包含"日期"、"时间"或"日期时间"。

3

我正在使用pandas读取csv文件

str,date,float,time,datetime
a,10/11/19,1.1,10:30:00,10/11/19 10:30
b,10/11/19,1.2,10:00:00,10/11/19 10:30
c,10/11/19,1.3,11:10:11,10/11/19 10:30

df = pd.read_csv(file)

现在我的业务需求是要告诉我哪个列是纯日期字段,哪个是纯时间字段,或者哪个是完整的日期时间字段。对于特定的列,我的代码如下:
try:
                    dt = pd.to_datetime(df[col])
                    dates = [obj.date() for obj in dt]
                    times = [obj.time() for obj in dt]

                    if dates and (set(times) == set([datetime.time(0, 0)])):
                        # Its a pure date field
                    elif <something>:
                       # Its a  pure time field
                    else:
                       #Its a Datetime field


except:
            # its not a datefield

我的代码问题是当只有时间字段时,pd.to_datetime会取今天的默认日期,以至于我无法将其与日期时间区分开来。是否有简单的解决方案?请帮我在上面的代码中填写“something”。


1
请添加一些数据,这样我们可以尝试复现您的问题。 - AKX
我已经添加了示例数据 @AKX - Rajat Jain
1个回答

6

如果想进行测试时间,pandas默认使用今天的日期,因此可能的解决方案是使用Series.dt.dateTimestamp.dateSeries.all对它们进行测试,看看列的所有值是否匹配。

此外,还可以通过Series.dt.floor删除时间后测试相同的日期数值:

df = pd.DataFrame({'a':['2019-01-01 12:23:10',
                        '2019-01-02 12:23:10'],
                   'b':['2019-01-01',
                        '2019-01-02'],
                   'c':['12:23:10',
                        '15:23:10'],
                   'd':['a','b']})
print (df)
                     a           b         c  d
0  2019-01-01 12:23:10  2019-01-01  12:23:10  a
1  2019-01-02 12:23:10  2019-01-02  15:23:10  b

def check(col):
    try:
        dt = pd.to_datetime(df[col])

        if (dt.dt.floor('d') == dt).all():
            return ('Its a pure date field')
        elif (dt.dt.date == pd.Timestamp('now').date()).all():
            return ('Its a pure time field')
        else:
            return ('Its a Datetime field') 
    except:
        return ('its not a datefield')


print (check('a'))
print (check('b'))
print (check('c'))
print (check('d'))
Its a Datetime field
Its a pure date field
Its a pure time field
its not a datefield

另一个想法是测试数字列,并默认返回非数字,以防止将数字转换为日期时间,但如果可能,所有日期时间都只包含今天的日期(f 列),则测试时间是否与匹配模式 HH:MM:SSH:MM:SSSeries.str.contains 不同:
df = pd.DataFrame({'a':['2019-01-01 12:23:10',
                        '2019-01-02'],
                   'b':['2019-01-01',
                        '2019-01-02'],
                   'c':['12:23:10',
                        '15:23:10'],
                   'd':['a','b'],
                   'e':[1,2],
                  'f':['2019-11-13 12:23:10',
                       '2019-11-13'],})
print (df)
                     a           b         c  d  e                    f
0  2019-01-01 12:23:10  2019-01-01  12:23:10  a  1  2019-11-13 12:23:10
1           2019-01-02  2019-01-02  15:23:10  b  2           2019-11-13

def check(col):
    if np.issubdtype(df[col].dtype, np.number):
        return ('its not a datefield')

    try:
        dt = pd.to_datetime(df[col])
        if (dt.dt.floor('d') == dt).all():
            return ('Its a pure date field')
        elif df[col].str.contains(r"^\d{1,2}:\d{2}:\d{2}$").all():
            return ('Its a pure time field')
        else:
            return ('Its a Datetime field') 
    except:
        return ('its not a datefield')


print (check('a'))
print (check('b'))
print (check('c'))
print (check('d'))
print (check('e'))
print (check('f'))
Its a Datetime field
Its a pure date field
Its a pure time field
its not a datefield
its not a datefield
Its a Datetime field

1
谢谢您的回答,它正在起作用。我有一个疑问:如果我的“datetime”列包含今天的日期和一些时间,那么它会返回“它是一个纯时间字段”。我是对的吗? - Rajat Jain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接