【问题标题】:python-pandas: dealing with NaT type values in a date columns of pandas dataframepython-pandas:处理熊猫数据框日期列中的 NaT 类型值
【发布时间】:2016-12-13 05:08:30
【问题描述】:

我有一个包含混合数据类型列的数据框,我申请了pd.to_datetime(df['DATE'],coerce=True) 并得到了以下数据框

CUSTOMER_name     DATE
 abc                 NaT
 def                 NaT
 abc               2010-04-15 19:09:08
 def               2011-01-25 15:29:37
 abc               2010-04-10 12:29:02

现在我想应用一些 agg 函数(这里我想通过 mailid 分组并取 min() 的 Date 来查找该 mailid 的第一次交易日期)。

df['DATE'] = [x.date() for x in df['DATE']]
#Here the value goes to 
 CUSTOMER_name     DATE
 abc               0001-255-255 ####how??
 def               0001-255-255  ###How??
 abc               2010-04-15
 def               2011-01-25
 abc               2010-04-10
#Then when i do a groupby and applying min on DATE
df.groupby('CUSTOMER_name')['DATE'].min()
#CUSTOMER_name     DATE
 abc               0001-255-255 ####i want 2010-04-10
 def               0001-255-255  ### i want 2011-01-25

任何人都可以建议,在转换为 date() 以及在进行 groupby 和 min() 时如何处理这个 NaT,如何排除 NaT 进行计算。

如果对于任何 customer_name 只有 NaT 将出现在 DATE 字段中,那么在 groupby 和 min() 上,我可以接受 nan 或 Null 值。

【问题讨论】:

  • 无法重现 0001-255-255。做df['DATE'] = [x.date() for x in df['DATE']] 时,我得到df['DATE'] 的同一列。就像@AmiTavory 在答案中所说,你的代码对我来说很好。当 DATE 字段中只有 NaT 时,我得到 NaT 值,groupby->min 和 groupby -> min 如果找到非 NaT 日期则忽略 NaT 值
  • 您能否发布所需/预期的数据集或接受@AmiTavory 的回答 - 如果它回答了您的问题?
  • @M.Klugerford:就像在 Ami Tovery 的例子中一样,他用 'NaT' 作为字符串形成了数据框。在我的情况下,首先使用任何字符串('sd','we','df')代替'NaT',然后执行 df['DATE'] = pd.to_datetime(df['DATE'],coerce=True)然后 df['DATE'] = [x.date() for x in df['DATE']]。我相信你会收到 0001-255-255。
  • 仍然无法重现@Satya 你使用的是什么版本的熊猫?
  • df = pd.DataFrame({ ... 'CUSTOMER_name': ['abc', 'def', 'abc', 'def', 'abc', 'fff'], .. 'DATE': ['T', 'N', '2010-04-15 19:09:08', '2011-01-25 15:29:37', '2010-04-10 12:29: 02', 'sa']}) 步骤 2) df['DATE'] = pd.to_datetime(df['DATE'],coerce=True)。步骤 3) df['DATE'] = [x.date() for x in df['DATE']] 在这之后 3) 我得到那些 0001-255-255 值。我在 pandas 0.16.1 和 python 3.4.1

标签: python datetime pandas


【解决方案1】:

假设你从这样的事情开始:

df = pd.DataFrame({
    'CUSTOMER_name': ['abc', 'def', 'abc', 'def', 'abc', 'fff'], 
    'DATE': ['NaT', 'NaT', '2010-04-15 19:09:08', '2011-01-25 15:29:37', '2010-04-10 12:29:02', 'NaT']})
df.DATE = pd.to_datetime(df.DATE)

(请注意,唯一的区别是添加映射到NaTfff)。

那么以下就是你所要求的:

>>> pd.to_datetime(df.DATE.groupby(df.CUSTOMER_name).min())
CUSTOMER_name
abc   2010-04-10 12:29:02
def   2011-01-25 15:29:37
fff                   NaT
Name: DATE, dtype: datetime64[ns]

这是因为groupby-min 已经在适用的情况下排除了缺失数据(尽管更改了结果的格式),并且最终的pd.to_datetime 将结果再次强制为datetime


要获取结果的日期部分(我认为这是一个单独的问题),请使用.dt.date

>>> pd.to_datetime(df.DATE.groupby(df.CUSTOMER_name).min()).dt.date
Out[19]: 
CUSTOMER_name
abc    2010-04-10
def    2011-01-25
fff           NaN
Name: DATE, dtype: object

【讨论】:

  • :谢谢。遵循您的建议后,我得到了日期时间的结果,现在如何将其转换为日期。我得到相同的 0001-255-255 值代替 NaT。
  • @Satya 不确定您的意思-dtype 表示它是一个日期时间。如果您想将其转换为其他格式,请提出新问题。
  • @Amy- 在 df_new= pd.to_datetime(df.DATE.groupby(df.CUSTOMER_name).min()).reset_index() ...... DATE 列的日期时间值到日期类型('2011-01-25').. 所以我正在尝试使用 df_new['DATE'] = [x.date() for x in df_new['DATE']].. . 现在在 o/pi 中得到 0001-255-255 代替 NaT。
  • @satya 我已经更新了答案,但请注意,你真的应该问一个单独的问题。
  • @Ami-Sure,虽然我会接受你的建议,但我已经问过这部分(如何在转换为 date() 以及在执行 groupby 和 min() 时处理这个 NaT,如何在问题中排除 NaT 进行计算)。谢谢。
【解决方案2】:

这是一个替代解决方案:

数据:

In [96]: x
Out[96]:
  CUSTOMER_name                 DATE
0           abc                    T
1           def                    N
2           abc  2010-04-15 19:09:08
3           def  2011-01-25 15:29:37
4           abc  2010-04-10 12:29:02
5           fff                   sa

解决方案:

In [100]: (x.assign(D=pd.to_datetime(x.DATE, errors='coerce').values.astype('<M8[D]'))
   .....:   .groupby('CUSTOMER_name')['D']
   .....:   .min()
   .....:   .astype('datetime64[ns]')
   .....: )
Out[100]:
CUSTOMER_name
abc   2010-04-10
def   2011-01-25
fff          NaT
Name: D, dtype: datetime64[ns]

说明:

首先,让我们创建一个新的虚拟列D,并截断时间部分:

In [97]: x.assign(D=pd.to_datetime(x.DATE, errors='coerce').values.astype('<M8[D]'))
Out[97]:
  CUSTOMER_name                 DATE          D
0           abc                    T        NaT
1           def                    N        NaT
2           abc  2010-04-15 19:09:08 2010-04-15
3           def  2011-01-25 15:29:37 2011-01-25
4           abc  2010-04-10 12:29:02 2010-04-10
5           fff                   sa        NaT

现在我们可以按CUSTOMER_name 分组并计算每个组的最小D

In [101]: x.assign(D=pd.to_datetime(x.DATE, errors='coerce').values.astype('<M8[D]')).groupby('CUSTOMER_name')['D'].min()
Out[101]:
CUSTOMER_name
abc    1.270858e+18
def    1.295914e+18
fff             NaN
Name: D, dtype: float64

最后将结果列转换为datetime64[ns] dtype:

In [102]: (x.assign(D=pd.to_datetime(x.DATE, errors='coerce').values.astype('<M8[D]'))
   .....:   .groupby('CUSTOMER_name')['D']
   .....:   .min()
   .....:   .astype('datetime64[ns]')
   .....: )
Out[102]:
CUSTOMER_name
abc   2010-04-10
def   2011-01-25
fff          NaT
Name: D, dtype: datetime64[ns]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 2017-09-02
    相关资源
    最近更新 更多