2017-04-13 64 views
4

請在此處指導我。我有以下數據框:計算一個單元格中存在多個值時列之間的差異

df 
    dob   date           
1 8/11/1966 3/1/1990, 5/1/2000, 8/1/2010 
2 6/13/1970 4/1/2014, 3/1/2016, 4/1/2017 
3 10/10/2010 4/13/2017 

我的目標是產生出一個差異列在多年的「DOB」和「日期」欄這樣間:

df 
    dob   date       difference     
1 8/11/1966 3/1/1990, 5/1/2000, 8/1/2010 23.570, 23.740, 23.992 
2 6/13/1970 4/1/2014, 3/1/2016, 4/1/2017 43.833, 45.751, 46.836 
3 10/10/2010 4/13/2017      6.512 

使用此代碼如下,

diff = (df['date'].sub(df['dob']))/365 
diff = (diff/np.timedelta64(1, 'D')).astype(float) 
df['difference'] = diff.round(3) 

我可以計算單個日期存在時的差異,但當一個單元格中有多個值用逗號分隔時,它不起作用。我怎樣才能實現我的目標?先謝謝你。

+4

劃分您的列中的數據。如果總是有三個日期,最好的辦法可能是將它們分成三列('df ['date1'],df ['date2'],df ['date3']')。如果日期數量可變,則會出現問題。您可以通過乘以行來分割日期(創建n行除日期以外的相同數據)或將python函數應用於每個單元格(可能會很慢,但您可能並不在乎行計數)。 –

回答

3

考慮數據框df

df = pd.DataFrame(dict(
     dob=['8/11/1996', '6/13/1970'], 
     date=[['3/1/1990', '5/1/2000', '8/1/2010'], 
       ['4/1/2014', '3/1/2016', '4/1/2017']] 
    )).reindex_axis(['dob', 'date'], 1) 

l = df.date.str.len() 
ilvl0 = df.index.repeat(l) 
ilvl1 = np.concatenate(l.apply(np.arange)) 
date = pd.Series(
    pd.to_datetime(np.concatenate(df.date.values)), 
    [ilvl0, ilvl1] 
) 

difference = date.sub(
    dob, level=0).dt.days.div(365.25).groupby(level=0).apply(list) 
df.assign(difference=difference) 

     dob       date   difference 
0 8/11/1996 [3/1/1990, 5/1/2000, 8/1/2010] [-6.45, 3.72, 13.97] 
1 6/13/1970 [4/1/2014, 3/1/2016, 4/1/2017] [43.8, 45.72, 46.8] 

OLD ANSWER

date_df = pd.to_datetime(
    pd.DataFrame(df.date.values.tolist(), df.index).stack() 
).unstack() 

一個小魔術...

df.assign(
    difference=date_df.sub(
     pd.to_datetime(df.dob), 0 
    ).stack().dt.days.groupby(level=0).apply(list) 
) 

     dob       date    difference 
0 1996-08-11 [3/1/1990, 5/1/2000, 8/1/2010] [-2355, 1359, 5103] 
1 1970-06-13 [4/1/2014, 3/1/2016, 4/1/2017] [15998, 16698, 17094] 

如果你想在幾年拉特呃比天

df.assign(
    difference=date_df.sub(
     pd.to_datetime(df.dob), 0 
    ).stack().apply(lambda x: x.days/365.25).round(2).groupby(level=0).apply(list) 
) 

     dob       date   difference 
0 8/11/1996 [3/1/1990, 5/1/2000, 8/1/2010] [-6.45, 3.72, 13.97] 
1 6/13/1970 [4/1/2014, 3/1/2016, 4/1/2017] [43.8, 45.72, 46.8] 
+0

謝謝你的回答!由於我的df ['date']中的數據類型是一個字符串而不是列表,因此在數據框中將其更改爲列表的最佳方法是什麼?先謝謝你。 – comproch

+1

@comprocho提前運行'df.date = df.date.str.split(',\ s *')' – piRSquared

相關問題