【问题标题】:Alternatives to looping in Pandas when you need to update a column based on another当您需要基于另一列更新列时,在 Pandas 中循环的替代方法
【发布时间】:2017-01-01 02:58:00
【问题描述】:

我有一个Pandasdataframe,其中包含我想转换为datetime 的文本日期。问题是我的一些文本日期是错误数据,因此无法转换。在无法转换日期的情况下,我想将Error 列更新为True 的值,并将Date 列设置为None,以便以后可以将其添加到格式为 datetime 的数据库列。

这是一个简化的例子。我的dataframe 可能有 100 万行和多个日期列,这需要完成,所以我需要一种更快的方法来执行此操作。我知道典型的约定是避免循环使用Pandas,但我想不出办法。

import pandas as pd
import numpy as np
import datetime

data = 1000 *[['010115', None],
        ['320115', None]]


df = pd.DataFrame(data=data,
                  columns=['Date', 'Error'])

for index, row in df.iterrows():
    try:
        datetime.datetime.strptime(row['Date'], '%d%m%y')
    except ValueError:
        row['Date'] = None
        row['Error'] = True
    except TypeError:
        pass

print df

【问题讨论】:

    标签: python python-2.7 datetime pandas dataframe


    【解决方案1】:

    您可以跳过df 的初始创建,而是从您需要的特定列构建它。

    # I push a list of first elements from data via a comprehension
    dates = pd.to_datetime([d[0] for d in data], format='%d%m%y', errors='coerce')
    
    # Construct df from scratch here
    df = pd.DataFrame({'Date': dates})
    df['Error'] = df.Date.isnull()
    df.head()
    


    时间

    这是使用已经构建的 df 与从头构建它的区别

    【讨论】:

    • @AlbertoGarcia-Raboso 我已经更新了我的答案。如您所见,您的答案和 jezreal 的答案之间的主要区别在于您利用了 OP 已经创建的数据框。我试图说明创建一个完整的数据帧只是为了覆盖它的内容是低效的。
    【解决方案2】:

    您可以将to_datetime 与参数errors='coerce'isnull 一起使用:

    data = 10 *[['010115', None],
            ['320115', None]]
    
    
    df = pd.DataFrame(data=data,
                      columns=['Date', 'Error'])
    
    print (df)
          Date Error
    0   010115  None
    1   320115  None
    2   010115  None
    3   320115  None
    4   010115  None
    5   320115  None
    6   010115  None
    7   320115  None
    8   010115  None
    9   320115  None
    10  010115  None
    11  320115  None
    12  010115  None
    13  320115  None
    14  010115  None
    15  320115  None
    16  010115  None
    17  320115  None
    18  010115  None
    19  320115  None
    
    df['Date'] = pd.to_datetime(df['Date'], format='%d%m%y',errors='coerce') 
    df['Error'] = df['Date'].isnull()
    print (df)
             Date  Error
    0  2015-01-01  False
    1         NaT   True
    2  2015-01-01  False
    3         NaT   True
    4  2015-01-01  False
    5         NaT   True
    6  2015-01-01  False
    7         NaT   True
    8  2015-01-01  False
    9         NaT   True
    10 2015-01-01  False
    11        NaT   True
    12 2015-01-01  False
    13        NaT   True
    14 2015-01-01  False
    15        NaT   True
    16 2015-01-01  False
    17        NaT   True
    18 2015-01-01  False
    19        NaT   True
    

    【讨论】:

    • 有必要将NaT 转换为None 吗?
    • 我将不得不尝试推送到数据库。我认为它会认识到这是一个Null/None 值,所以可能不会。只是为了澄清NaT 不是时间?
    • 是的,现在不是时候。
    • 如果原始数据集中缺少 NaTNaN,有没有办法区分它?
    • 不,是一样的。 DatetimeNaN
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-09
    • 1970-01-01
    • 2016-12-21
    • 2023-03-25
    • 1970-01-01
    • 2018-11-22
    • 2015-05-02
    相关资源
    最近更新 更多