在pandas中创建两行不同的列

时间:2015-12-30 12:27:35

标签: python pandas

我有一个pandas数据框,其中一列中包含哈希,另一列中包含日期。我想创建一个带有年龄的新列,即第一个日期与特定哈希值和当前日期之间的差异。例如,数据框inf包含

inf.head(5)
                                   id       date
0  00047331-29e7-4165-833f-3efcfc2ea90f 2015-08-19
1  0005b350-31ac-443c-8244-21a34120c83d 2015-08-20
2  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-10
3  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-07
4  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-04

我通过

添加一个名为age的列
inf['age'] = pd.Series(np.zeros(len(inf)), index=inf.index)

现在我想将其转换为

                               id       date  age
0  00047331-29e7-4165-833f-3efcfc2ea90f 2015-08-19    0
1  0005b350-31ac-443c-8244-21a34120c83d 2015-08-20    0
2  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-10    0
3  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-07    -3
4  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-04    -6

最后一列是特定ID的第一个日期与该行中的日期之间的差异。我目前正在使用它执行此操作:

datedict={}
for count in range(len(inf)):
    try:
        inf['age'][count]=inf['date'][count]-datedict[inf['id'][count]]
    except KeyError:
        datedict[inf['udid'][count]]=inf['date'][count]

这很有效,但令人厌恶。花了一个多小时就完成了10万条记录。有没有更好的方法来执行此操作?

2 个答案:

答案 0 :(得分:1)

您可以使用groupby方法进行哈希,然后使用transform方法date列和iloc获取第一个元素。您还需要使用pd.to_datetime将日期列转换为日期时间:

In [402]: df
Out[402]: 
                                     id       date
0  00047331-29e7-4165-833f-3efcfc2ea90f 2015-08-19
1  0005b350-31ac-443c-8244-21a34120c83d 2015-08-20
2  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-10
3  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-07
4  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-04

dates = df.groupby('id')['date'].transform(lambda x:  (x - x.iloc[0])) 

In [405]: dates
Out[405]: 
0   1970-01-01
1   1970-01-01
2   1970-01-01
3   1969-12-29
4   1969-12-26
Name: date, dtype: datetime64[ns]

我不确定为什么从1970-01-01开始打印,但你可以通过从pd.Timestamp('1970-01-01')

中减去来解决这个问题
In [408]: dates - pd.Timestamp('1970-01-01')
Out[408]: 
0    0 days
1    0 days
2    0 days
3   -3 days
4   -6 days
Name: date, dtype: timedelta64[ns]

如果您只需要值,则可以使用dt.days,然后将其传递到新列age

df['age'] = (dates - pd.Timestamp('1970-01-01')).dt.days

In [415]: df
Out[415]: 
                                     id       date  age
0  00047331-29e7-4165-833f-3efcfc2ea90f 2015-08-19    0
1  0005b350-31ac-443c-8244-21a34120c83d 2015-08-20    0
2  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-10    0
3  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-07   -3
4  0007da63-6fa6-4c0d-a1b1-b09fb0353853 2015-08-04   -6

答案 1 :(得分:0)

Anton's相似,味道略有不同:

df['date'] = pd.to_datetime(df['date'])

def Age(df):
    df.reset_index(drop=True, inplace=True)
    df['age'] = [x-df.date[0] for x in df.date]
    return df

df = df.groupby('id').apply(Age)