我有一个比我在这里展示的数据框更大的数据框,但是我想要做的是在一系列中有某些价值(甚至更好的整个数据框)将该值更改为a没有。我需要这些是None,所以我可以将数据帧写入数据库,它将被识别为null。
series = (['2014/06/05 13:03:56', '2014/07/23 13:03:56', None, '2014/08/21 13:03:56'])
data = pd.DataFrame(series)
0 2014/06/05 13:03:56
1 2014/07/23 13:03:56
2 None
3 2014/08/21 13:03:56
data = pd.to_datetime(data[0], coerce=True)
data
0 2014-06-05 13:03:56
1 2014-07-23 13:03:56
2 NaT
3 2014-08-21 13:03:56
Name: 0, dtype: datetime64[ns]
data = data.map(str)
data
0 2014-06-05 13:03:56
1 2014-07-23 13:03:56
2 NaT
3 2014-08-21 13:03:56
Name: 0, dtype: object
data.replace(to_replace='NaT', value=None)
0 2014-06-05 13:03:56
1 2014-07-23 13:03:56
2 2014-07-23 13:03:56
3 2014-08-21 13:03:56
Name: 0, dtype: object
在上面的例子中,当我尝试替换NaT'数据框实际上用前面的值填充值,而不是None。这不会有帮助,因为它必须是无。在实际的数据框架中,我使用它通常会抛出一个类型错误,告诉我我不能用方法垫替换None。我在这里使用的是日期时间系列,但实际上我不仅仅需要日期时间系列。它似乎应该是熊猫的基本功能,但我无法找到答案。
谢谢, 科林
答案 0 :(得分:5)
首先,您的代码无效的原因是那些NaT
值不是字符串'NaT'
,它们是值pd.NaT
。但是,既然我不认为修复会实际上给你你想要的东西,那么我们暂时忽略它。
Pandas DataFrame
,就像它构建的NumPy ndarray
一样,是一个紧凑的类型化的低级值。这就是它小巧,快速和类型安全的原因。但这本质上意味着它只能存储指定类型的值。 None
不是datetime64[ns]
类型的值。
更具体地说,datetime64[ns]
只能保存64位整数,这些整数将日期时间表示为自纪元以来的纳秒,而None
不是64位整数。
Pandas确实有一个特殊的价值来处理这个问题,称为NaT
,用于“非时间”;这是None
最接近你可以在任何类型的日期时间字段中得到的东西(就像对于浮点数更熟悉的NaN
)。这就是你已经拥有的。
与此同时,Pandas特别支持None
在各个不同的地方尝试做你经常想要的东西 - 存储NaN / NaT / 0,或重复最后一个值,或者各种各样的其他事情。但是,如果那不是你想要的,那就没什么用了。
如果您确实需要None
,那么唯一的方法是存储正常的盒装Python对象而不是键入的低级值,这可以通过dtype=object
来实现。然后,您可以将任何Python值粘贴到任何元素中,当然也包括None
。
但这样做很大程度上违背了使用Pandas和NumPy的目的。您可能最好使用NaT
并更改代码的其余部分 - 或者期望NaT
您当前期望的None
,或者包裹DataFrame
在提取或打印输出期间将NaT
值转换为None
的内容。
为了完整性,如果你想变得疯狂,没有什么能阻止你定义optionaldatetime64[ns]
dtype,就像datetime64[ns]
一样,只是它使用为NaT
保留的特殊值来表示而是None
。或者它甚至可以保留另一个特殊值,或者说整数,表示None
,而单独留下NaT
。无论哪种方式,这将是很多工作,它将完全打破任何依赖于日期时间算术的操作(任何d - NaT == NaT
d
,但d - None
是TypeError
对于任何d
...),最终它不会比我能想到的任何目的的包装解决方案更好......
答案 1 :(得分:0)
最后,这符合我的需求。我不认为map(str)在我为问题提供的代码中工作,但是它在我将其分配给一个字段而不是整个数据帧的地方工作。
def change_date_to_string(field):
data[field] = data[field].map(str)
data[field].loc[data[field] == 'NaT'] = None
change_date_to_string(field='usr_datetime')