[英]Using loc on two columns to perform calculations that replace values of another column
我已經被困在這條路上太久了。 我想要做的就是創建一個名為Duration Target Date
的新列,該列源自Standard Duration Days
+ Date/Time Created
。 到目前為止,以下是我的代碼: 從我的 POV,我認為這段代碼將從 0 迭代到數據幀的長度。 如果Standard Duration Days
列中有“No Set Standard Duration”,則轉到我的 else 語句並用空白覆蓋給定的單元格(與我初始化它時相同)。 但是,如果代碼意識到除了“No Set Standard Duration”之外還有什么,那么它應該添加來自列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
或可能是np.nan
值。 僅出於顯示目的,這些才會被轉換,例如df['Duration Target Date'].fillna('')
。
這里有幾個問題。 首先,您似乎將loc
與iloc
混淆了。 很容易做到。 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
row-wise 的方法:
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)
注意:由於您尚未提供任何數據,因此未進行測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.