【问题标题】:How to replace a string value with None - python, pandas dataframe如何用 None 替换字符串值 - python,pandas 数据框
【发布时间】:2015-04-27 21:21:12
【问题描述】:

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

谢谢, 科林

【问题讨论】:

  • NaT 不是字符串,它是一个特殊的“不是时间”值,类似于浮点数的 NaN。因此,只需将to_replace='NaT' 更改为to_replace=pd.NaT,它就会完成您想做的事情。但我不认为你想做的就是你真正想要的。
  • @abarnert 将 dtype 转换为 object,日期时间将转换为一些 int 值:In [506]: df.replace(pd.NaT, 'None') ​ Out[506]: 0 1401973436000000000 1 1406120636000000000 2 None 3 1408626236000000000 Name: 0, dtype: object
  • @EdChum:这就是为什么我说“我不认为你想做的就是你真正想要的”。
  • @EdChum:此外,您的代码将 NaT 替换为字符串 'None',这会导致 不同 问题,然后将其替换为实际的 None 会。并不是说任何一个都是他真正想要的,但是…… Pandas 试图以半智能的方式处理None 值;有时它们会转换为 NaN/NaT/0,有时它们的意思是“重复最后一个值”等。但是 'None' 没有任何特殊含义;就是“一些不知道怎么处理的值,还是换object吧”。
  • @EdChum:我不知道总体上是好是坏……但由于这正是他偶然得到的行为并且想知道如何摆脱,我想我会有同意你的观点,在这个用户的情况下情况更糟。 :)

标签: python pandas null


【解决方案1】:

首先,您的代码不起作用的原因是那些NaT 值不是字符串'NaT',它们是值pd.NaT。但由于我认为修复它实际上不会给你想要的东西,所以我们暂时忽略它。

Pandas DataFrame 和 NumPy ndarray 一样,是一个紧凑的类型化低级值数组。这就是它体积小、速度快且类型安全的原因。但这本质上意味着它只能存储指定类型的值。而None 不是datetime64[ns] 类型的值。

更具体地说,datetime64[ns] 只能保存 64 位整数,表示自纪元以来的日期时间为纳秒,None 不是 64 位整数。

Pandas 确实有一个特殊的值来处理这个问题,称为NaT,表示“Not a Time”;这是最接近 None 的东西,您可以在任何类型的日期时间字段中获得(就像更熟悉的 NaN 用于浮点数一样)。这就是你已经拥有的。


同时,Pandas 在各种不同的地方对None 提供了特殊支持,它们试图经常做你想做的事——存储 NaN/NaT/0,或重复最后一个值,或各种其他事情.但是,如果这不是您想要的,那就没有多大帮助了。


如果您确实需要None,唯一的方法是存储普通的装箱 Python 对象,而不是使用 dtype=object 执行的键入的低级值。然后,您可以将任何 Python 值粘贴到任何元素中,当然包括None

但是这样做在很大程度上违背了使用 Pandas 和 NumPy 的目的。您可能最好使用NaT,并更改您的其余代码——或者在您当前期望None 的地方期待NaT,或者将DataFrame 包装在转换NaT 值的东西中在提取或打印输出期间发送至None


为了完整起见,如果你想发疯,没有什么能阻止你定义一个类似于datetime64[ns]optionaldatetime64[ns] dtype,除了它使用为NaT 保留的特殊值来表示None。或者它甚至可以保留另一个特殊值,或者一个完整的值,表示None,而单独留下NaT。无论哪种方式,这将是很多工作,它会完全破坏任何依赖于日期时间算术的操作(d - NaT == NaT 用于任何d,但d - NoneTypeError 用于任何d...),最终它并不比我能想到的任何目的的包装器解决方案更好......

【讨论】:

  • 伙计们,首先感谢您抽出一些时间来解释我实际所说的内容。我确实需要 None 而不是丢失数据的其他能指。如果我尝试通过 NaT,则数据库会引发错误。我正在使用 pyodbc (code.google.com/p/pyodbc/wiki/DataTypes)。公平地说,我对数据框的底层结构和我正在使用的数据类型知之甚少,我很感激在这里为我拼写出来的努力。我将尝试将数据框包装在将 NaT(和其他一些)转换为 None 的东西中
  • @ColinO'Brien:我不知道 pyodbc(自上个世纪以来我没有在任何语言中使用过 ODBC……),但是我使用的大多数 Python 数据库接口都提供了一种转换未知数的方法数据库 API 端的数据类型,这可能比 Pandas 端更容易。
【解决方案2】:

最后,这满足了我的需求。我不认为 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')

【讨论】:

    猜你喜欢
    • 2021-09-02
    • 2013-06-11
    • 1970-01-01
    • 2012-12-30
    • 2018-02-03
    • 2021-05-13
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多