2015-05-26 19 views
1

我有一個熊貓數據框,一列是溫度(人類),但價值混合,攝氏和華氏,我想打破這個列成兩列(保持原來的一個)熊貓分成兩列,並得到名稱後綴錯誤

#C Temp will be added to the end of df 
df = df.join(df.Temp.apply(lambda x: np.nan if x > 43 else x)) 

#F Temp will be added to the end of df 
df = df.join(df.Temp.apply(lambda x: np.nan if x < 43 else x)) 

我想df.Temp.apply(lambda x: np.nan if x < 43 else x)將返回一系列將要連接的df結束,但我得到這個錯誤

ValueError: columns overlap but no suffix specified: Index([u'Temp'], dtype='object') 

回答

2

麻煩的是,上了隱name屬性 - 飛行計算Series內部的電話號碼join也將爲'Temp',因爲它是從該列導出的計算結果。由於'Temp'已存在於DataFrame中,因此它引發一個異常以表明它不知道要使用哪種名稱更改(通過後綴)來防止名稱重疊。

可以提供rsuffix參數join將指定字符串追加到名稱,從的加入操作來列(在這種情況下,函數調用內部的一個)。例如:

df = df.join(df.Temp.apply(lambda x: np.nan if x > 43 else x), 
      rsuffix='_Celsius') 

獲得在修改後的輸出數據框命名"Temp_Celsius"列。也可以選擇使用lsuffix提供一個字符串,該字符串將被附加到左側操作數,如果您希望改爲更改該列名稱(或者您可以提供兩個如果您不希望列保留原始名稱)。

但是,請注意,在使用join時,您總是省略任何on參數(加入標準) - 這意味着您默認按索引「加入」。真的,你想要的是簡單地寫入存在,從舊的列派生的新列,它給你申報的名稱的機會,如:

df['Celsius'] = df.Temp.apply(lambda x: np.nan if x > 43 else x) 

這是可取的,因爲它更清楚地表達你意圖,這是不加入,但創建一個專欄。此外,由於缺省連接方法爲'left',如果碰巧有重複的索引,則最終可能會針對左側索引中的每個副本加入多次,並且因爲該索引與右側索引相同(因此也會有重複),這可能意味着你會在每次連接時默默地和錯誤地引入更多重複項。

您也可以選擇使用map而不是apply,因爲在訪問某列時,您將使用Series對象。

+0

非常感謝,但爲什麼我會使用applymap並在所有的df單元上應用函數,這裏有不同類型的數據和所有其他的東西? – Hakim

+1

我在中間擴展了一點,以突出爲什麼簡單地創建一個新的數據列在這裏比使用'join'更有意義。另一方面,請注意我並不是建議使用'applymap'這是一個DataFrame方法,而是使用普通的'map',它是一個Series方法。 'Series.map'專門用於元素操作,而'apply'則對函數進行一些額外的檢查,可以一次性對整個'.values'數據對象進行矢量操作。 – ely

0

我要補充說可以更有效地和優雅的計算所需的系列使用where方法:

df['Celsius'] = df.Temp.where(df.Temp > 43) 

這是一個矢量化溶液,這意味着內循環中C. .apply實現應避免因爲它使用python循環並且可能會慢很多。此外,lambda函數在可能的情況下應避免,因爲它們也會在很多迭代中減慢速度。熊貓作爲這些類型問題的內置功能的負載。