如果我有数据框
name | datetime | price
---------------------------
APL | 10-1-12 | 1.92
BBC | 10-1-12 | 4.16
CPL | 10-1-12 | 4.99
APL | 10-2-12 | 2.05
BBC | 10-2-12 | 5.16
CPL | 10-2-12 | 3.99
我想创建一个新列:APL_price,以及其他任何一个列 名称的日期时间与APL的日期时间相匹配,我希望它充满了 那个日期的APL价格如下:
name | datetime | price | APL_price
-------------------------------------
APL | 10-1-12 | 1.92 | 1.92 (or null is ok)
BBC | 10-1-12 | 4.16 | 1.92
CPL | 10-1-12 | 4.99 | 1.92
APL | 10-2-12 | 2.05 | 2.05 (or null)
BBC | 10-2-12 | 5.16 | 2.05
CPL | 10-2-12 | 3.99 | 2.05
我正在考虑编写一个辅助函数来迭代所有东西 并找到一个日期时间匹配,但不确定是否有更快的方式。
答案 0 :(得分:0)
您可以为所有值NaN
创建APL
,而不是Series.where
NaN
,然后通过ffill
向前填充替换df['APL_price'] = df['price'].where(df['name'] == 'APL').ffill()
:
!=
mask
的替代解决方案和df['APL_price'] = df['price'].mask(df['name'] != 'APL').ffill()
的反转掩码:
print (df)
name datetime price APL_price
0 APL 10112 1.92 1.92
1 BBC 10112 4.16 1.92
2 CPL 10112 4.99 1.92
3 APL 10212 2.05 2.05
4 BBC 10212 5.16 2.05
5 CPL 10212 3.99 2.05
print (df['price'].where(df['name'] == 'APL'))
0 1.92
1 NaN
2 NaN
3 2.05
4 NaN
5 NaN
Name: price, dtype: float64
详情:
groupby
更一般的解决方案在第一步中类似,但是datetime
的{{1}}与ffill
和bfiil
一起用于替换NaN
s两个方向:
name = 'BBC'
df[name + '_price'] = df['price'].where(df['name'] == name)
df[name + '_price'] = (df.groupby('datetime')[name + '_price']
.apply(lambda x: x.ffill().bfill()))
print (df)
name datetime price BBC_price
0 APL 10112 1.92 4.16
1 BBC 10112 4.16 4.16
2 CPL 10112 4.99 4.16
3 APL 10212 2.05 5.16
4 BBC 10212 5.16 5.16
5 CPL 10212 3.99 5.16