如何用None-python,pandas dataframe替换字符串值

时间:2015-04-24 08:52:29

标签: python pandas null

我有一个比我在这里展示的数据框更大的数据框,但是我想要做的是在一系列中有某些价值(甚至更好的整个数据框)将该值更改为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。我在这里使用的是日期时间系列,但实际上我不仅仅需要日期时间系列。它似乎应该是熊猫的基本功能,但我无法找到答案。

谢谢, 科林

2 个答案:

答案 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 - NoneTypeError对于任何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')