[英]Pandas DataFrame - Fill NaNs of columns based on values of other columns
我有幾年的廣泛數據框:
df = pd.DataFrame(index=pd.Index([29925, 223725, 280165, 813285, 956765], name='ID'),
columns=pd.Index([1991, 1992, 1993, 1994, 1995, 1996, '2010-2012'], name='Year'),
data = np.array([[np.NaN, np.NaN, 16, 17, 18, 19, np.NaN],
[16, 17, 18, 19, 20, 21, np.NaN],
[np.NaN, np.NaN, np.NaN, np.NaN, 16, 17, 31],
[np.NaN, 22, 23, 24, np.NaN, 26, np.NaN],
[36, 36, 37, 38, 39, 40, 55]]))
Year 1991 1992 1993 1994 1995 1996 2010-2012
ID
29925 NaN NaN 16.0 17.0 18.0 19.0 NaN
223725 16.0 17.0 18.0 19.0 20.0 21.0 NaN
280165 NaN NaN NaN NaN 16.0 17.0 31.0
813285 NaN 22.0 23.0 24.0 NaN 26.0 NaN
956765 36.0 36.0 37.0 38.0 39.0 40.0 55.0
每行中的值是每個人的年齡,每個人都有一個唯一的 ID。 我想根據每行中的現有年齡值在每一行的每一年中填充此數據框的NaN
。
例如,ID 29925
在1993
中是 16 ,我們知道它們在1992
是 15 ,在1991
是 14 ,因此我們想在1992
和1991
列中將NaN
替換為29925
。 同樣,我想根據29925
的現有年齡值替換2010-2012
列中的NaN
。 假設29925
在2010-2012
列中比1996
年大 15 年。 對整個數據框(即所有 ID)執行此操作的最快方法是什么?
# imports we need later
import numpy as np
import pandas as pd
這不是一種特別有效的方法,但它確實有效。 我將省略你的最后一個專欄,以使事情更系統化。
df
:
df = pd.DataFrame(index=pd.Index([29925, 223725, 280165, 813285, 956765], name='ID'),
columns=pd.Index([1992, 1992, 1993, 1994, 1995, 1996], name='Year'),
data = np.array([[np.NaN, np.NaN, 16, 17, 18, 19],
[16, 17, 18, 19, 20, 21],
[np.NaN, np.NaN, np.NaN, np.NaN, 16, 17],
[np.NaN, 22, 23, 24, np.NaN, 26],
[35, 36, 37, 38, 39, 40]]))
計算每個人的出生日期:
dob=[]
for irow, row in enumerate(df.iterrows()):
dob.append(np.asarray([int(each) for each in df.columns]) - np.asarray(df.iloc[irow,:]))
或者,如果您喜歡列表推導:
dob = [np.asarray([int(each) for each in df.columns]) - np.asarray(df.iloc[irow,:]) for irow, row in enumerate(df.iterrows())]
現在dob
是這樣的:
[array([ nan, nan, 1977., 1977., 1977., 1977.]),
array([1976., 1975., 1975., 1975., 1975., 1975.]),
array([ nan, nan, nan, nan, 1979., 1979.]),
array([ nan, 1970., 1970., 1970., nan, 1970.]),
array([1956., 1956., 1956., 1956., 1956., 1956.])]
使用np.unique制作一個更簡單的 dob 列表,刪除nans :
dob_filtered=[np.unique(each[~np.isnan(each)])[0] for each in dob]
dob_filtered
現在看起來像這樣:
[1977.0, 1975.0, 1979.0, 1970.0, 1956.0]
將此列表附加到 dataframe:
df['dob']=dob_filtered
使用dob
列填寫df
的NaN
:
for irow, row in enumerate(df.index):
for icol, col in enumerate(df.columns[:-2]):
df.loc[row,col] = col - df['dob'][row]
刪除dob
列(只是為了獲取原始列而已,否則不重要):
df.drop(['dob'],axis=1)
獲得:
Year 1992 1992 1993 1994 1995 1996
ID
29925 15.0 15.0 16.0 17.0 18.0 19.0
223725 17.0 17.0 18.0 19.0 20.0 21.0
280165 13.0 13.0 14.0 15.0 16.0 17.0
813285 22.0 22.0 23.0 24.0 25.0 26.0
956765 36.0 36.0 37.0 38.0 39.0 40.0
IE
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.