【问题标题】:Month and Date messed up in pandas dataframe熊猫数据框中的月份和日期搞砸了
【发布时间】:2021-01-12 01:37:15
【问题描述】:

我遇到了这样一种情况,即我的数据框中的几个日期的月份和日期都搞砸了。例如,这里是输入:

df['work_date'].head(15)

    0     2018-01-01
    1     2018-02-01
    2     2018-03-01
    3     2018-04-01
    4     2018-05-01
    5     2018-06-01
    6     2018-07-01
    7     2018-08-01
    8     2018-09-01
    9     2018-10-01
    10    2018-11-01
    11    2018-12-01
    12    2018-01-13
    13    2018-01-14
    14    2018-01-15

日期存储为string。如您所见,日期格式为 yyyy-dd-mm,直到 1 月 12 日,然后变为 yyyy-mm-dd。数据框由 3 年的数据组成,这种模式在所有年份的所有月份都重复。

我的预期输出是将日期标准化为dddd-mm-yy 的格式,如下所示。

0     2018-01-01
1     2018-01-02
2     2018-01-03
3     2018-01-04
4     2018-01-05
5     2018-01-06
6     2018-01-07
7     2018-01-08
8     2018-01-09
9     2018-01-10
10    2018-01-11
11    2018-01-12
12    2018-01-13
13    2018-01-14
14    2018-01-15

以下是我编写的代码,它可以完成工作。基本上,我拆分日期字符串并进行一些字符串操作。但是,如您所见,它不太漂亮。我正在检查除了df.applyloops 之外是否还有其他优雅的解决方案。

def func(x):
    d = x.split('-')
    print(d)
    if (int(d[1]) <= 12) & (int(d[2]) <= 12) :
        d = [d[0],d[2],d[1]]
        x = '-'.join(d)
        return x
    else:
        return x
df['work_date'] = df['work_date'].apply(lambda x:func(x))

【问题讨论】:

  • 这些数据是从哪里来的?
  • 它来自第三方给我们,我们无法控制它如何分享给我们
  • 那么他们是否为您提供数据库连接或 CSV 文件或...?
  • 就个人而言,我会让数据提供者纠正他们的错误,但那是咨询建议而不是编程建议
  • @sharathnatraj 以后,只需告诉提供商不要在生成 .csv 文件后保存它,或者如果您有同事,告诉他们在发送给您之前不要保存文件。如果 .csv 文件是由美国用户生成的,而英国用户打开它并重新保存它(反之亦然),那么日期格式可能会搞砸,所以根本问题是导致日期获取的人搞砸了-他们应该停止覆盖.csv文件并将原始文件发送给您,或者他们应该将该列保存为excel或其他解决方案中的TEXT。

标签: python-3.x pandas dataframe date


【解决方案1】:

您可以根据以下事实来更新该列,即它是有序的并且只有一个日期并且一年中的所有日子都连续包含在内:

df['Date'] = pd.date_range(df['work_date'].min(), '2018-01-12', freq='1D')
# you can specify df['work_date'].min() OR df['work_date'].max) OR A STRING. It really depends on what format your minimum and your maximum is
df
Out[1]: 
     work_date       date
0   2018-01-01 2018-01-01
1   2018-02-01 2018-01-02
2   2018-03-01 2018-01-03
3   2018-04-01 2018-01-04
4   2018-05-01 2018-01-05
5   2018-06-01 2018-01-06
6   2018-07-01 2018-01-07
7   2018-08-01 2018-01-08
8   2018-09-01 2018-01-09
9   2018-10-01 2018-01-10
10  2018-11-01 2018-01-11
11  2018-12-01 2018-01-12
12  2018-01-13 2018-01-13
13  2018-01-14 2018-01-14
14  2018-01-15 2018-01-15

为了使这更加动态,您还可以做一些try / except 如下所示:

minn = df['work_date'].min()
maxx = df['work_date'].max()
try:
    df['Date'] = pd.date_range(minn, maxx, freq='1D')
except ValueError:
    s = maxx.split('-')
    df['Date'] = pd.date_range(minn, f'{s[0]}-{s[2]}-{s[1]}', freq='1D')
except ValueError:
    s = minn.split('-')
    df['Date'] = pd.date_range(f'{s[0]}-{s[2]}-{s[1]}', maxx, freq='1D')
df

【讨论】:

  • @PaulH 谢谢。我也再次考虑了一下,并认为date_range 可能是这里最好的解决方案(我在编辑答案后看到了你的评论)。
  • 非常好的@DavidErickson。我刚刚做了pd.date_range('2018-01-01', '2020-12-30', freq='1D'),这就是我所需要的!!
猜你喜欢
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 2013-12-31
  • 2023-03-20
  • 1970-01-01
  • 2017-09-26
相关资源
最近更新 更多