【问题标题】:How can I replace a timestamp in a dataframe with a string if the column is not all timestamps?如果列不是所有时间戳,如何用字符串替换数据框中的时间戳?
【发布时间】:2021-07-15 00:54:08
【问题描述】:

我正在尝试使用无法编辑的 Excel 电子表格构建机器学习模型。 .xls 中的一些列存在格式问题,因此某些数据显示为日期时间戳,而不是 str 或 int。以下是 pd 数据框的示例:

0     40-49   premeno      15-19                  0-2       yes          3   
1     50-59      ge40      15-19                  0-2        no          1   
2     50-59      ge40      35-39                  0-2        no          2   
3     40-49   premeno      35-39                  0-2       yes          3   
4     40-49   premeno      30-34  **2019-05-03 00:00:00**       yes          2

在第 4 行中,3-5 的值被意外格式化为日期(在 xls 中显示为 03 May),因此被指定为数据框中的日期时间戳。我尝试了很多方法将2019-05-03 00:00:00 替换为3-5,包括:

df['column'] = df['column'].replace([('2019-05-03 00:00:00')], '3-5') 

并使用 Timestamp.replace 但似乎都不起作用。关于如何用正确的数据替换这些格式错误的数据点有什么想法吗?

【问题讨论】:

  • 防止 Excel 在这里变得聪明的一个助手是指定单元格的内容,如 ="3-5" 或预先将单元格的类型更改为“文本”。

标签: python excel pandas dataframe datetime


【解决方案1】:

可能有更简单的方法,但您可能需要使用积极的环顾四周来申请 re.search

import re

pat1 = '(?<=\*{2}\d{4}-0\d-0)(\d)(?= 00:00:00\*\*)'

pat2 = '(?<=\*{2}\d{4}-0)(\d)(?=-0\d 00:00:00\*\*)'

df['column'] = df['column'].astype(str).apply(
        lambda x: (re.search(pat2, '**2019-05-03 00:00:00**').group()
                   +'-'+re.search(pat1, '**2019-05-03 00:00:00**').group())
                   if '**' in x else x
     )

【讨论】:

  • 您的意思是在 x 中搜索模式吗? ** 是怎么回事?我不明白...如果您有匹配项,为什么不搜索整个日期时间模式并提取组?就像例如使用pat='\d{4}-(\d{2})-(\d{2})\ 00:00:00',您可以提取match.group(2).lstrip('0')+'-'+match.group(1).lstrip('0'),但我认为在lambda 中这样做并不好。
【解决方案2】:

您可以使用apply 迭代列并检查元素是否为pd.Timestamp 的实例;如果是,则提取字符串“day-month”,否则保持原样。

例如:

import pandas as pd

# what you have is something like (mixed datatype column/Series)
df = pd.DataFrame({'label': ['0-2', '1-3', pd.Timestamp('2019-05-03')]})

# iterate the column with an apply, extract day-month string if pd.Timestamp
df['label1'] = df['label'].apply(lambda x: f"{x.day}-{x.month}" if isinstance(x, pd.Timestamp) else x)

# ... to get
df['label1'] 
0    0-2
1    1-3
2    3-5
Name: label1, dtype: object

【讨论】:

  • 我们知道那些类似日期时间的字符串目前是日期时间格式吗?由于他们是从 excel 中读取的,因此它们可能只是字符串,除非 read_excel() 自动执行此操作。
  • @KristianCanler 如果 Excel 中的“3-5”等原始条目后来在熊猫系列中显示为“2019-05-03 00:00:00”,则可能 i> Excel(一如既往的聪明......)转换为 Excel 的内部日期表示(自 1900 年以来的天数),然后在导入时转换为 pandas 日期时间。
猜你喜欢
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 2021-02-28
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
相关资源
最近更新 更多