0

我需要找到在 python 中有日期的 2 列之间的绝对天数差异。这在 excel 中很容易,但我想要在 python 中。

我有一个 xlsx 文件,我已将其读取到 python 数据框(使用pd.read_excel),其中示例数据读取如下: 列具有纯文本格式的 ddmmyyyy/dmmyyyy 的日期详细信息。

A B
1102012
26071993 27122007
28062010 3122015
16012010 21022016
02082015 14092010

现在我需要创建一个新列 C,其中包含 A 和 B 之间的绝对天数差。A 可以小于或大于 B。
如果 B 为空,那么它应该考虑当前日期来计算天数。但 A 不会有空/NULL 值。

所以输出将是天数的差异:

C
2432
5267
1984
2227
1783

我遵循的方法是:

  1. 将 A 和 B 转换为 8 位,因为我们在 A 和 B 的某些值中只有 7 位 - 使用df['A'].apply(lambda x: '{0:0>8}'.format(x))
  2. 使用将 A 转换为日期时间字段pd.to_datetime
  3. 通过复制 B 值和所有非 NULL 日期值创建另一个临时列 CC(即用当前日期替换 NULL/空)
  4. 然后求 A 和 CC 之间的绝对差(天数)

我被困在第三步,无法继续。有没有更简单的方法来做到这一点?

4

2 回答 2

3

首先格式化选项是个好主意。避免混淆哪个是日或月。

# Recreate dataframe
df = pd.DataFrame([["1102012", pd.np.NaN],["26071993","27122007"],
                   ["28062010","3122015"],["16012010","21022016"],
                   ["02082015","14092010"]], columns=["A","B"]) 
print(df)
>>>
          A         B
0   1102012       NaN
1  26071993  27122007
2  28062010   3122015
3  16012010  21022016
4  02082015  14092010

print(df.dtypes)
>>>
A    object
B    object
dtype: object

所以我们正在使用的数据框在上面。数据类型都是object(字符串)。如果你能确认这一步就好了,因为其他一切都源于这里。

# convert some datetimes
# Assumption is that column A is not sparse - there are no NaNs
# Column B can be NaN so make it today if so
m = df["B"].isnull()
df.loc[m, "B"] = pd.datetime.now().strftime("%d%m%Y") 
print(df)
>>>
          A         B
0   1102012  03062019
1  26071993  27122007
2  28062010   3122015
3  16012010  21022016
4  02082015  14092010

# now we zero pad some numbers
df['A'] = df['A'].apply(lambda x: '{0:0>8}'.format(x))
df['B'] = df['B'].apply(lambda x: '{0:0>8}'.format(x))
print(df)
>>>
          A         B
0  01102012  03062019
1  26071993  27122007
2  28062010  03122015
3  16012010  21022016
4  02082015  14092010

然后使用 to_datetime:

df["A"] = pd.to_datetime(df["A"], format="%d%m%Y")
df["B"] = pd.to_datetime(df["B"], format="%d%m%Y")
print(df)
>>>
           A          B
0 2012-10-01 2019-06-03
1 1993-07-26 2007-12-27
2 2010-06-28 2015-12-03
3 2010-01-16 2016-02-21
4 2015-08-02 2010-09-14

print(df.dtypes)
>>>
A    datetime64[ns]
B    datetime64[ns]
dtype: object

然后差异

df["Diff"] = (df["A"] - df["B"]).abs()
print(df)
>>>
           A          B      Diff
0 2012-10-01 2019-06-03 2436 days
1 1993-07-26 2007-12-27 5267 days
2 2010-06-28 2015-12-03 1984 days
3 2010-01-16 2016-02-21 2227 days
4 2015-08-02 2010-09-14 1783 days

# or
df["Diff"] = (df["A"] - df["B"]).abs().dt.days
print(df)
>>>
           A          B  Diff
0 2012-10-01 2019-06-03  2436
1 1993-07-26 2007-12-27  5267
2 2010-06-28 2015-12-03  1984
3 2010-01-16 2016-02-21  2227
4 2015-08-02 2010-09-14  1783
于 2019-05-30T15:28:32.807 回答
1

编辑解释错误

正如您在评论中所说的错误。这意味着您的列A不是 dtype object。它是int32int64。运行此命令以确认(我更改了示例数据列Adtype 以演示错误):

df.dtypes

Out[2866]:
A     int32
B    object
dtype: object

在使用之前str.zfill,您需要将您的更改dfobject

df = df.astype(str)

Out[2870]:
A    object
B    object
dtype: object

将 dtype 转换为 后object,一切正常。


zfill(8)将 0 填充到字符串并使用pd.to_datetimewith将它们转换为日期时间coerce,并使用今天的日期。接下来,做减法and , make和 get fromfilnaNaTABabsdaystimedelta

注意:添加预处理以将dfdtype 转换为objectusingastype(str)

df = df.astype(str) 
df1 = df.apply(lambda x: pd.to_datetime(x.str.zfill(8), format='%d%m%Y', errors='coerce')).fillna(pd.datetime.today().date())
df1.A.sub(df1.B).abs().dt.days

Out[2599]:
0    2432
1    5267
2    1984
3    2227
4    1783
dtype: int64
于 2019-05-30T19:25:27.830 回答