簡體   English   中英

在兩列上使用 loc 來執行替換另一列值的計算

[英]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('')

這里有幾個問題。 首先,您似乎將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 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM