在两列上使用 loc 执行替换另一列值的计算



我被困在这条路上太久了。我要做的就是创建一个名为Duration Target Date的新列,该列派生自Standard Duration Days+Date/Time Created.以下是我到目前为止的代码: 从我的 POV 来看,我认为这段代码将从 0 迭代到数据框的长度。如果Standard Duration Days列中有"未设置标准持续时间",则转到我的 else 语句并用空白覆盖给定单元格(与我初始化它相同(。但是,如果代码意识到除了"未设置标准持续时间"之外没有任何内容,则应将列Standard Duration Days给定单元格中的值与列Date/Time Created相加。我希望新值位于新列中Duration Target Date相应的索引处。

newDF["Duration Target Date"] = ""
for i in range(0,len(newDF)):
if newDF.loc[i,"Standard Duration Days"] != "No Set Standard Duration":
newDF.loc[i,"Duration Target Date"] = (timedelta(days = int(newDF.loc[i,"Standard Duration Days"])) + newDF.loc[i,"Date/Time Created"])
else:
newDF.loc[i,"Duration Target Date"] == ""

我注意到这部分有效,但最终停止工作......当我运行这个时,我也会收到一个错误:"KeyError 326"

我只会添加列并留下NaT(不是时间(错误。

df = pd.DataFrame({
"Standard Duration Days": [3, 5, "No Set Standard Duration"],
"Date/Time Created": ['2019-01-01', '2019-02-01', '2019-03-01']
})
# 1. Convert string dates to pandas timestamps.
df['Date/Time Created'] = pd.to_datetime(df['Date/Time Created'])
# 2. Create time deltas, coercing errors.
delta = pd.to_timedelta(df['Standard Duration Days'], unit='D', errors='coerce')
# 3. Create new column by adding delta to 'Date/Time Created'.
df['Duration Target Date'] = (df['Date/Time Created'] + delta).dt.normalize()
>>> df
Standard Duration Days Date/Time Created Duration Target Date
0                         3        2019-01-01           2019-01-04
1                         5        2019-02-01           2019-02-06
2  No Set Standard Duration        2019-03-01                  NaT

向数字列添加文本会将整个列转换为object这会占用更多内存且效率较低。 通常,人们希望将空值保留为np.nan,或者在整数的情况下保留为哨兵值。 仅出于显示目的,它们才会被转换,例如df['Duration Target Date'].fillna('').

这里有几个问题。首先,看起来您将lociloc混淆了。很容易做到。loc按实际索引查找,该索引可能是也可能不是整数位置索引。但是您的i in range (0, len(newDF))是按整数位置索引迭代的。因此,您正在获取KeyError 326,因为您要到达数据帧的第 326 行,但它的索引实际上不是 326。您可以通过查看来检查这一点print(newDF.iloc[320:330]).

第二个也是更重要的问题:您几乎从不想遍历 pandas 数据帧中的行。请改用一次应用于完整列的矢量化函数。对于需要条件分配的情况,相关函数np.where

boolean_filter = newDF.loc[:,"Standard Duration Days"] != "No Set Standard Duration"
value_where_true = (timedelta(days = newDF.loc[:,"Standard Duration Days"].astype('int'))) + newDF.loc[:,"Date/Time Created"])
value_where_false = ""
newDF["Duration Target Date"] = np.where(boolean_filter, value_where_true, value_where_false) 

这是一种按行使用.apply的方法:

newDF['Standard Duration Days'] = newDF['Standard Duration Days'].astype(int)
newDF['Duration Target Date'] = (newDF
.apply(lambda x:, x["Standard Duration Days"] + x["Date/Time Created"] if x["Standard Duration Days"] != "No Set Standard Duration" else None,axis=1)

注意:由于您未提供任何数据,因此不会对其进行测试。

最新更新