当您需要基于另一列更新列时,在 Pandas 中循环的替代方法

Posted

技术标签:

【中文标题】当您需要基于另一列更新列时,在 Pandas 中循环的替代方法【英文标题】:Alternatives to looping in Pandas when you need to update a column based on another 【发布时间】: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

【问题讨论】:

【参考方案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

以上是关于当您需要基于另一列更新列时,在 Pandas 中循环的替代方法的主要内容,如果未能解决你的问题,请参考以下文章

更新另一列时自动更新sql列

基于针对另一列的参考表更新 Pandas 数据框列的问题

更新另一列时,使用列名作为 PL/SQL 关联数组的键

Pandas - 基于 str 包含从另一列创建新列/值

当用户在 MS Access 中修改表中的另一列时,如何在 SQL Server 中将列设置为今天的日期 [关闭]

在 Pandas 中基于一列保存数据并由另一列命名