我有一个dataframe(df1)如下:
datetime m d 1d 2d 3d
2014-01-01 1 1 2 2 3
2014-01-02 1 2 3 4 3
2014-01-03 1 3 1 2 3
...........
2014-12-01 12 1 2 2 3
2014-12-31 12 31 2 2 3
我还有另一个dataframe(df2)如下:
datetime m d
2015-01-02 1 2
2015-01-03 1 3
...........
2015-12-01 12 1
2015-12-31 12 31
我想将df1的1d 2d 3d列值合并到df2。
有两个条件:
(1)只能合并df1和df2中的m和d。
(2)如果df2索引%30 == 0的索引不合并,则这些索引的1d 2d 3d的值可以为Nan。
I mean I want the new dataframe of df2 like as following:
datetime m d 1d 2d 3d
2015-01-02 1 2 Nan Nan Nan
2015-01-03 1 3 1 2 3
...........
2015-12-01 12 1 2 2 3
2015-12-31 12 31 2 2 3
提前致谢!
我认为您需要在loc之前添加NaN,然后在左侧联接中添加merge:
np.random.seed(10)
N = 365
rng = pd.date_range('2015-01-01', periods=N)
df_tr_2014 = pd.DataFrame(np.random.randint(10, size=(N, 3)), index=rng).reset_index()
df_tr_2014.columns = ['datetime','7d','15d','20d']
df_tr_2014.insert(1,'month', df_tr_2014['datetime'].dt.month)
df_tr_2014.insert(2,'day_m', df_tr_2014['datetime'].dt.day)
#print (df_tr_2014.head())
N = 366
rng = pd.date_range('2016-01-01', periods=N)
df_te = pd.DataFrame(index=rng)
df_te['month'] = df_te.index.month
df_te['day_m'] = df_te.index.day
df_te = df_te.reset_index()
#print (df_te.tail())
df2 = df_te.copy()
df1 = df_tr_2014.copy()
df1 = df1.set_index('datetime')
df1.index += pd.offsets.DateOffset(years=1)
#correct 29 February
y = df1.index[0].year
df1 = df1.reindex(pd.date_range(pd.datetime(y,1,1), pd.datetime(y,12,31)))
idx = df1.index[(df1.index.month == 2) & (df1.index.day == 29)]
df1.loc[idx, :] = df1.loc[idx - pd.Timedelta(1, unit='d'), :].values
df1.loc[idx, 'day_m'] = idx.day
df1[['month','day_m']] = df1[['month','day_m']].astype(int)
df1[['7d','15d', '20d']] = df1[['7d','15d', '20d']].astype(float)
df1.loc[np.arange(len(df1.index)) % 30 == 0, ['7d','15d','20d']] = 0
df1 = df1.reset_index()
print (df1.iloc[57:62])
index month day_m 7d 15d 20d
57 2016-02-27 2 27 2.0 0.0 1.0
58 2016-02-28 2 28 2.0 3.0 5.0
59 2016-02-29 2 29 2.0 3.0 5.0
60 2016-03-01 3 1 0.0 0.0 0.0
61 2016-03-02 3 2 7.0 6.0 9.0
谢谢,the年如何?如果2016年2月为29,2015年2月为29。如果2015年2月没有29。2016年2月的28和29相同
嗯,所以您每个月需要30天,而没有2月(28,29)?还是在每个月的最后一天需要nans(28,29,30,31)?
谢谢,我的意思是2016年是leap年,2月是29,但是2015年没有2月29日。在这种情况下,如果去年没有29,则2月29日的数据与的数据相同。 2月28日
好的,对不起,我忘了您的评论。一月有31天,您还需要选择30天吗?二月明白了。三月也是31 ...所以还需要选择30?谢谢。
感谢您的宝贵意见。我的意思是考虑the年(仅考虑2月)。例如,如果要获取2016年2月29日的一年前的数据(即2015年2月29日),则2016年为a年。但是由于它不是a年,因此没有2015年2月29日的数据。在这种情况下,2016年2月29日一年前的数据与2016年2月28日相同。
谢谢,我已经通过f_tr2.index [i]-pd.offsets.DateOffset(years = 1)解决了,您之前已经回答过。还是谢谢你!
感谢您的评论。我的主要问题是我不明白,为什么要减去一年零一天?你能解释一下吗?
谢谢,我还没有详细解释。但是,在检查完我的答案代码后(我将发布答案),您将理解它。
确实我有相同的想法-代码可以提供帮助。如果可能的话,我尝试优化它...
也可能是因为您的代码有必要使用更大的数据框,可以免费使用我的数据示例并在必要时进行更改。
谢谢,我的代码花了更多时间。你能优化一下吗
但是没有30天有什么问题。您能再解释一下吗?
请稍候,我上传了其他代码
我已经上传了有关此问题的新答案,但要花更多的时间(如果可能),因为我使用了循环,因此您可以对其进行优化
您能否测试样本数据是否可用于您的解决方案-我将其添加到您的答案中。
谢谢,你真好!
是的,这并不容易,但我很高兴它能奏效。祝好运!
嗨@jezrael,有一个问题:stackoverflow.com/questions/44946555/
您好@jezrael,有一个问题:stackoverflow.com/questions/45564867/谢谢!
您是否需要NaN? df = df.shift(1, freq=D)不起作用?
很好回答的人;)
@c ??? s ???? - 谢谢 :)
为什么不只删除df1中与df2中的(m, d)对不匹配的行?
df_new = df2.drop(df2[(not ((df2.m == df1.m) & (df2.n == df1.n)).any()) or (df2.index % 30 == 0)].index)
或类似的规定。
链接到相关答案。
我对Pandas不太熟悉,也没有测试上面的示例。
感谢您的评论,condition2怎么样:如果df2索引%30 == 0的索引,我们不合并它
是的,感谢您指出@ tktktk0711
df_te是df2
df_tr_2014是df1
7d 15d 20分别是1d 2d 3d。 size_df_te是df_te的长度,month和day_m是m,d在df2中
df_te['7d'] = 0
df_te['15d'] = 0
df_te['20d'] = 0
mj = 0
dj = 0
for i in range(size_df_te):
if i%30 != 0:
m = df_te.loc[i,'month']
d = df_te.loc[i,'day_m']
if (m== 2) & (d == 29):
m = 2
d = 28
dk_7 = df_tr_2014.loc[(df_tr_2014['month']==m) & (df_tr_2014['day_m']==d)]['7d']
dk_15 = df_tr_2014.loc[(df_tr_2014['month']==m) & (df_tr_2014['day_m']==d)]['15d']
dk_20 = df_tr_2014.loc[(df_tr_2014['month']==m) & (df_tr_2014['day_m']==d)]['20d']
df_te.loc[i,'7d'] = float(dk_7)
df_te.loc[i,'15d'] = float(dk_15)
df_te.loc[i,'20d'] = float(dk_20)
编辑:
样本数据:
np.random.seed(10)
N = 365
rng = pd.date_range('2014-01-01', periods=N)
df_tr_2014 = pd.DataFrame(np.random.randint(10, size=(N, 3)), index=rng).reset_index()
df_tr_2014.columns = ['datetime','7d','15d','20d']
df_tr_2014.insert(1,'month', df_tr_2014['datetime'].dt.month)
df_tr_2014.insert(2,'day_m', df_tr_2014['datetime'].dt.day)
#print (df_tr_2014.head())
N = 365
rng = pd.date_range('2015-01-01', periods=N)
df_te = pd.DataFrame(index=rng)
df_te['month'] = df_te.index.month
df_te['day_m'] = df_te.index.day
df_te = df_te.reset_index()
#print (df_te.head())