【问题标题】:Merge pandas dataframe on time and another column按时合并熊猫数据框和另一列
【发布时间】:2016-12-21 04:48:47
【问题描述】:

我有两个 pandas 数据帧,我正试图将它们组合成一个数据帧。以下是我的设置方式:

a = {'date':['1/1/2015 00:00','1/1/2015 00:15','1/1/2015 00:30'], 'num':[1,2,3]}
b = {'date':['1/1/2015 01:15','1/1/2015 01:30','1/1/2015 01:45'], 'num':[4,5,6]}

dfa = pd.DataFrame(a)
dfb = pd.DataFrame(b)

dfa['date'] = dfa['date'].apply(pd.to_datetime)
dfb['date'] = dfb['date'].apply(pd.to_datetime)

然后我从每个中找到earliest 和latest 时间戳,并创建一个以date 系列开头的新数据框:

earliest = min(dfa['date'].min(), dfb['date'].min())
latest = max(dfa['date'].max(), dfb['date'].max())

date_range = pd.date_range(earliest, latest, freq='15min')

dfd = pd.DataFrame({'date':date_range})

然后我想将它们全部合并到一个以dfd 为基础的数据帧中,因为它将包含所有正确的时间戳。所以我合并了dfd 和dfa,一切都很好:

dfd = pd.merge(dfd, dfa, how = 'outer', on = 'date')

但是,当我将它与 dfb 合并时,date 系列变得很乱,我不知道为什么。

dfd = pd.merge(dfd, dfb, how = 'outer', on = ['date','num'])

...产量:

                  date  num
0  2015-01-01 00:00:00  1.0
1  2015-01-01 00:15:00  2.0
2  2015-01-01 00:30:00  3.0
3  2015-01-01 00:45:00  NaN
4  2015-01-01 01:00:00  NaN
5  2015-01-01 01:15:00  NaN
6  2015-01-01 01:30:00  NaN
7  2015-01-01 01:45:00  NaN
8  2015-01-01 01:15:00  4.0
9  2015-01-01 01:30:00  5.0
10 2015-01-01 01:45:00  6.0

我希望4.0 填写2015-01-01 01:15:00 时隙等,而不是创建新行。

或者如果我尝试:

dfd = pd.merge(dfd, dfb, how = 'outer', on = 'date')

我明白了:

                 date  num_x  num_y
0 2015-01-01 00:00:00    1.0    NaN
1 2015-01-01 00:15:00    2.0    NaN
2 2015-01-01 00:30:00    3.0    NaN
3 2015-01-01 00:45:00    NaN    NaN
4 2015-01-01 01:00:00    NaN    NaN
5 2015-01-01 01:15:00    NaN    4.0
6 2015-01-01 01:30:00    NaN    5.0
7 2015-01-01 01:45:00    NaN    6.0

这也不是我想要的(只想要一个 num 列)。任何帮助将不胜感激。

【问题讨论】:

  • 似乎merge() 正在填写缺失的日期时间(即您不能从 00:30:00 跳转到 01:15:00)。我说只是手动删除行,使用条件索引等等。

标签: python pandas merge


【解决方案1】:
dfa.set_index('date').combine_first(dfb.set_index('date')) \
    .asfreq('15T').reset_index()

                 date    num
0 2015-01-01 00:00:00 1.0000
1 2015-01-01 00:15:00   2.00
2 2015-01-01 00:30:00   3.00
3 2015-01-01 00:45:00    nan
4 2015-01-01 01:00:00    nan
5 2015-01-01 01:15:00   4.00
6 2015-01-01 01:30:00   5.00
7 2015-01-01 01:45:00   6.00

另一种解决方案

dfa.append(dfb).set_index('date').asfreq('15T').reset_index()

【讨论】:

  • 谢谢@piRSquared,但我更新了我的问题,我想要一个num 列。
  • @piRSquared 你在 jupyter notebook 上吗?你以前怎么有这么大的桌子?
  • @MohammadYusufGhazi 我不知道,这不是我摘下它的原因。看起来很荒谬。我在Mac上,我想我以某种方式调整了我的屏幕截图。我会解决的。
  • 爱上单线。谢谢@piRSquared。
  • @pshep123 刚刚给了你一个较短的。
【解决方案2】:

先合并dfa和dfb:

d = pd.merge(dfa, dfb, on=['date','num'], how='outer')

然后将结果与您定义的 dfd 结合起来:

result = pd.merge(d, dfd, on='date', how='outer')
print result.sort('date')

输出:

                 date  num
0 2015-01-01 00:00:00  1.0
1 2015-01-01 00:15:00  2.0
2 2015-01-01 00:30:00  3.0
6 2015-01-01 00:45:00  NaN
7 2015-01-01 01:00:00  NaN
3 2015-01-01 01:15:00  4.0
4 2015-01-01 01:30:00  5.0
5 2015-01-01 01:45:00  6.0

【讨论】:

  • 谢谢,但这并不能填补缺失的时间戳。
  • 是的,很抱歉我首先误解了丢失数据,我现在编辑我的答案
  • 非常感谢@lingpingta。
【解决方案3】:

这行得通:

a = {'date':['1/1/2015 00:00','1/1/2015 00:15','1/1/2015 00:30'], 'num':[1,2,3]}
b = {'date':['1/1/2015 01:15','1/1/2015 01:30','1/1/2015 01:45'], 'num':[4,5,6]}

dfa = pd.DataFrame(a)
dfb = pd.DataFrame(b)

dfa['date'] = dfa['date'].apply(pd.to_datetime)
dfb['date'] = dfb['date'].apply(pd.to_datetime)

earliest = min(dfa['date'].min(), dfb['date'].min())
latest = max(dfa['date'].max(), dfb['date'].max())

date_range = pd.date_range(earliest, latest, freq='15min')

dfd = pd.DataFrame({'date':date_range})


df_dates = pd.merge(dfa, dfb, how = 'outer')
df_final = pd.merge(dfd, df_dates, how = 'outer')

df_final

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    相关资源
    最近更新 更多