pd.to_datetime生成“仅针对唯一值索引对象重新索引”错误

8

我使用pandas的pd.to_datetime时,遇到了一些意外的行为。我的pd.Series如下:

0         2017-01-06 14:37:16
1         2017-01-27 00:00:00
2         2017-01-18 00:00:00
3         2017-01-26 00:00:00
4                        None
                 ...         
454823    2019-10-22 11:20:03
454824                   None
454825    2019-07-11 00:00:00
454826                   None
454827    2019-07-15 00:00:00
Name: colx, Length: 454828, dtype: object

当我将其强制转换为datetime时,我得到了以下结果:

pd.to_datetime(df.colx, errors='coerce')

InvalidIndexError:重新索引仅适用于唯一值索引对象

虽然这似乎表明索引中存在重复值,但我运行了以下测试来检查是否是导致错误的原因:

all(df.colx.index == range(df.colx.shape[0]))
# True

df.index.duplicated().any()
# False

看起来没有重复的索引。是什么导致了这个错误?


你能将这个数据框切成更小的部分,仍然生成错误吗?你能得到多小的部分并仍然生成此错误? - Scott Boston
@yatu,你正在使用哪个版本的pandas?如果版本小于0.25.0,请尝试在pd.to_datetime中指定cache=True。我认为你在该列中遇到了pd.NaTNone都是空值的问题,这个问题已经在0.25版本中得到了解决。 - ALollz
1
谢谢 @alollz 的建议,我明天会尝试。 - yatu
你是完全正确的 @ALollz,就是这样解决了。我的serius有很多Nonepd.NaT,使用np.NaT填充解决了问题。不过我的pandas版本是0.25.2。所以显然这仍然会引起问题。 - yatu
请随意添加答案。否则我会添加。在这里有一个将非常有用,我很惊讶没有找到任何相关的@ALollz。 - yatu
这似乎在今天发布的 pandas v1.2.5 版本中出现了回归 (2021年6月22日)。 - Simon Ejsing
3个回答

26

您收到的错误与您的Index无关。它与这个问题有关,该问题应该已在0.25.0版本中得到解决。该问题与使用pd.to_datetime时多个null类型的处理不一致有关。

import pandas as pd

pd.core.algorithms.unique([pd.NaT, None])
#array([NaT, None], dtype=object) # That is, `pd.NaT` and `None` are unique

pd.Index([pd.NaT, None]).is_unique
#False   # However, Index.unique considers them duplicated

对这种不同行为的处理应该在 0.25.0 版本中得到修复。如果仍然存在问题,解决方法是确保您在要转换的列中只有一个 null 值的表示方法。在这种情况下,您可以使用日期时间 null 值进行 .fillna 操作。


pd.to_datetime(df.colx.fillna(pd.NaT), errors='coerce')

pd.__version__
#'0.25.0'

pd.to_datetime([pd.NaT, None])
#DatetimeIndex(['NaT', 'NaT'], dtype='datetime64[ns]', freq=None)

2
我也遇到了同样的问题。升级到当前最新的Pandas版本(1.1.2)没有帮助,但你在这里建议的解决方法确实为我解决了问题。我猜这个bug实际上并没有被修复或者出现了回归。 - Steve Jorgensen
2
这似乎仍然是一个未解决的问题。我在Pandas版本1.2.0上遇到了这个问题。但用pd.NaT替换可以解决。感谢这里提供的解决方案。 - CheradenineZK

3

从纠正一个误解开始

我注意到你的检查程序存在以下错误:

调用df.index.duplicated().any()只检查索引是否有重复。

为了调查这个问题,我使用了你的数据创建了一个输入文件(只包含10行数据):

colx
2017-01-06 14:37:16
2017-01-27 00:00:00
2017-01-18 00:00:00
2017-01-26 00:00:00
None
2019-10-22 11:20:03
None
2019-07-11 00:00:00
None
2019-07-15 00:00:00

我调用了read_csv函数,然后调用了df.duplicated().any(),结果为True,因此在colx列中存在重复项。

运行df.duplicated(),你会看到对于索引为68(第二个和第三个None字符串实例)的行,打印出了True

另一个检查:运行df.info(),你将得到:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 1 columns):
colx    10 non-null object
dtypes: object(1)
memory usage: 208.0+ bytes

这证实了没有任何元素具有“true”None值。只有包含“None”的字符串

另一个要注意的问题是:all(df.colx.index == range(df.colx.shape[0])) 只检查索引是否包含连续的数字,这对于colx的内容没有任何明示意义。

如何读取您的DataFrame

我猜想你是通过例如read_csv来读取DataFrame的,没有进行任何转换,所以 colx列是object(实际上是字符串)类型。

在这种情况下,如果第一个元素包含None(一个字符串),则尝试调用pd.to_datetime会失败,因为它无法转换为datetime

应该怎么做

请尝试以下方法:

  1. When reading the DataFrame, pass na_values=['None'] parameter. It provides that elements containing None are not left as strings, but are converted to NaNs.

  2. Print the DataFrame (read from my limited source). Instead of None (a string) there will be NaN - a special case of float.

  3. Run df.info(). This time the printout will be:

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 10 entries, 0 to 9
    Data columns (total 1 columns):
    colx    7 non-null object
    dtypes: object(1)
    memory usage: 208.0+ bytes
    

    Note that there are only 7 non-null values, out of total 10, so the 3 remaining are "true" None values, which Pandas prints as NaN.

  4. Run pd.to_datetime(df.colx). This time there should be no error.


0

我有同样的错误,对我来说下面的方法有效:

pd.to_datetime(df.colx.astype(str))

我怀疑这个解决方案是否能解决“None”或“NaN”值的问题。你已经用OP的数据测试过了吗? - craigb

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