我从两个不同的气象站获取某个位置的数据。 80年代安装了一个站,90年代中期安装了另一个站。由于仪器错误,旧站的读数变得不可靠。新站也有几个缺失记录的实例。
我计划在安装新电台之前使用旧电台的数据创建完整的天气配置文件,并附加新电台的数据。当新站(NaN)出现仪器故障时,我也希望使用旧站的数据。
df_new =pd.DataFrame(
{'Date': {0: '01/01/1994', 1: '01/02/1994', 2: '01/03/1994', 3: '01/04/1994'},
'Rain': {0: 0, 1: 0, 2: 0, 3: 0},
'TMAX': {0: -5.5, 1: np.nan, 2: -1.5, 3: np.nan},
'TMIN': {0: -11.64, 1: -10.55, 2: np.nan, 3: -11.41},
'WIND': {0: 4.1, 1: 6.8, 2: 5.4, 3: 9.6}})
df_old = pd.DataFrame(
{'Date': {0: '01/01/1980', 1: '01/02/1980', 2: '01/03/1980', 3: '01/04/1980'},
'Rain': {0: 0, 1: 0, 2: 0, 3: 0},
'TMAX': {0: -5.5, 1: -3.5, 2: -1.5, 3: -2.8},
'TMIN': {0: -11.64, 1: -10.55, 2: -14.33, 3: -11.41},
'WIND': {0: 4.1, 1: 6.8, 2: 5.4, 3: 9.6}})
如何组合两个df并创建一个新的df(df_complete)?
df_complete
Date Rain TMAX TMIN WIND
01/01/1980 0 -5.5 -11.64 4.1
01/02/1980 0 -3.5 -10.55 6.8
01/03/1980 0 -1.5 -14.33 5.4
.
.
01/01/1994 0 -5.5 -11.64 4.1
01/02/1994 0 5.7 -10.55 6.8
01/03/1994 0 -1.5 -10.58 5.4
.
.
12/31/2014 0 -4.9 -10.21 3.5
为了让自己更清楚,使用 df_old
答案 0 :(得分:2)
尝试使用combine_first()。
import numpy as np
import pandas as pd
from pandas.tseries.offsets import DateOffset
df_new =pd.DataFrame(
{'Date': {0: '01/01/1994', 1: '01/02/1994', 2: '01/03/1994', 3: '01/04/1994'},
'Rain': {0: 0, 1: 0, 2: 0, 3: 0},
'TMAX': {0: -5.5, 1: np.nan, 2: -1.5, 3: np.nan},
'TMIN': {0: -11.64, 1: -10.55, 2: np.nan, 3: -11.41},
'WIND': {0: 4.1, 1: 6.8, 2: 5.4, 3: 9.6}})
df_old = pd.DataFrame(
{'Date': {0: '01/01/1980', 1: '01/02/1980', 2: '01/03/1980', 3: '01/04/1980'},
'Rain': {0: 0, 1: 0, 2: 0, 3: 0},
'TMAX': {0: -5.5, 1: -3.5, 2: -1.5, 3: -2.8},
'TMIN': {0: -11.64, 1: -10.55, 2: -14.33, 3: -11.41},
'WIND': {0: 4.1, 1: 6.8, 2: 5.4, 3: 9.6}})
# Date Type Cast
df_old['Date'] = pd.to_datetime(df_old['Date'])
df_new['Date'] = pd.to_datetime(df_new['Date'])
# I'm assuming a 14 year roll forward.
df_old['DateForward'] = df_old['Date'] + pd.DateOffset(years=14)
df_old.set_index('DateForward',inplace=True)
df_new.set_index('Date',inplace=True)
df_new.combine_first(df_old).reset_index(drop=True)
Date Rain TMAX TMIN WIND
0 1980-01-01 0 -5.5 -11.64 4.1
1 1980-01-02 0 -3.5 -10.55 6.8
2 1980-01-03 0 -1.5 -14.33 5.4
3 1980-01-04 0 -2.8 -11.41 9.6
答案 1 :(得分:1)
首先,标记您的数据,以便在合并后知道来源:
df_old['source'] = 'old'
df_new['source'] = 'new'
使用辅助函数只需两个语句即可实现结果:
df_combined = combine(df_new, df_old,
cols=['TMAX', 'TMIN', 'WIND'],
on='Date')
pd.concat([df_old, df_combined])
=>
Date Rain TMAX TMIN WIND source updated
0 2015-01-02 0 0 6 0 old NaN
1 2015-01-03 1 8 -4 9 old NaN
2 2015-01-04 1 -3 9 12 old NaN
3 2015-01-05 0 -4 5 16 old NaN
4 2015-01-06 0 -2 9 5 old NaN
5 2015-01-07 1 3 8 12 old NaN
6 2015-01-08 0 9 -2 6 old NaN
7 2015-01-09 1 7 -3 11 old NaN
...
19 2015-01-21 0 -5 -1 8 new
20 2015-01-22 0 2 -5 1 new
21 2015-01-23 1 7 8 17 new
22 2015-01-24 0 6 5 8 new TMAX
23 2015-01-25 1 -3 0 13 new TMAX
24 2015-01-26 1 4 -3 8 new
25 2015-01-27 0 1 -2 7 new TMIN
26 2015-01-28 0 -4 5 0 new
27 2015-01-29 1 9 -3 3 new TMIN
请注意,combine
还会告诉我们哪些值已更新。
combine
功能如下。它将我原来的答案概括为pandas.combine_first
功能的选择性版本。选择性意义,您可以指定合并键和列,而无需摆弄索引:
def combine(df_left, df_right, cols=None, on=None):
def check(r):
updated = []
for c in cols:
xc = '%s_x' % c
yc = '%s_y' % c
if math.isnan(r[xc]):
r[xc] = r[yc]
updated.append(c)
r['updated'] = ','.join(updated)
return r
left_expanded = df_left.merge(df_right, on=on, how='left')
left_expanded = left_expanded.apply(check, axis=1)
columns = [('%s' % c, c.replace('_x', ''))
for c in left_expanded.columns]
left_expanded.rename(columns=dict(columns), inplace=True)
return left_expanded[list(df_left.columns) + ['updated']]
我的初步答案仍可在历史记录中使用,或使用full solution。感谢Dickster bringing up combine_first
,这激发了我对原始方法的概括。
答案 2 :(得分:0)
尝试pandas concatentate:
ne = @newevent.Master
我真的不确定你想要用NaN做些什么。您是否尝试使用来自每个数据帧的匹配日期填充空观察值?
如果它们具有相同的观察数量/顺序,您可以执行以下操作:
ne = @newevent.master