为了账号安全,请及时绑定邮箱和手机立即绑定

Python Dataframes:根据条件合并两个数据帧(Pandas)

Python Dataframes:根据条件合并两个数据帧(Pandas)

有只小跳蛙 2022-12-20 12:12:48
假设我有这两个 DataFrame:DATAFRAME 1    onset  offset0       1     2001     201     4002     401     6003     601     8004     801    10005    1001    12006    1201    14007    1401    16008    1601    18009    1801    200010   2001    220011   2201    240012   2401    260013   2601    280014   2801    300015   3001    320016   3201    340017   3401    360018   3601    380019   3801    400020   4001    420021   4201    440022   4401    460023   4601    480024   4801    500025   5001    520026   5201    540027   5401    560028   5601    580029   5801    6000DATAFRAME 2   onset rhythm_name  rhythm_code  offset0      1         NSR          100    27601   2761  JUNCTIONAL         4000    39382   3939         NSR          100    6000我的目标是将两个数据帧与起始偏移间隔合并,并添加它们各自的rhythm_name和rhythm_code以获得如下内容:    onset  offset  rhythm_name  rhythm_code0       1     200        NSR          100 1     201     400        NSR          1002     401     600        NSR          1003     601     800        NSR          1004     801    1000        NSR          1005    1001    1200        NSR          1006    1201    1400        NSR          1007    1401    1600        NSR          1008    1601    1800        NSR          1009    1801    2000        NSR          10010   2001    2200        NSR          10011   2201    2400        NSR          10012   2401    2600        NSR          10013   2601    2800        Null         Null我可以用什么来做到这一点?我找不到解决这个问题的方法。我试过类似的东西:df1["rhythm_name"] = df2[(df1['onset'] >= df2['onset']) & (df1['offset'] <= df2['offset'])])我明白了:ValueError: Can only compare identically-labeled Series objects
查看完整描述

2 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

您可以pd.merge_asof, 并屏蔽第二个条件:


dfm = pd.merge_asof(df1, df2, on='onset', direction='backward', suffixes=('','_y'))

dfm[['rhythm_name', 'rhythm_code']] = (dfm[['rhythm_name', 'rhythm_code']]

                                          .where(dfm['offset'] <= dfm['offset_y']))

dfm.drop('offset_y', axis=1)

输出:


    onset  offset rhythm_name  rhythm_code

0       1     200         NSR        100.0

1     201     400         NSR        100.0

2     401     600         NSR        100.0

3     601     800         NSR        100.0

4     801    1000         NSR        100.0

5    1001    1200         NSR        100.0

6    1201    1400         NSR        100.0

7    1401    1600         NSR        100.0

8    1601    1800         NSR        100.0

9    1801    2000         NSR        100.0

10   2001    2200         NSR        100.0

11   2201    2400         NSR        100.0

12   2401    2600         NSR        100.0

13   2601    2800         NaN          NaN

14   2801    3000  JUNCTIONAL       4000.0

15   3001    3200  JUNCTIONAL       4000.0

16   3201    3400  JUNCTIONAL       4000.0

17   3401    3600  JUNCTIONAL       4000.0

18   3601    3800  JUNCTIONAL       4000.0

19   3801    4000         NaN          NaN

20   4001    4200         NSR        100.0

21   4201    4400         NSR        100.0

22   4401    4600         NSR        100.0

23   4601    4800         NSR        100.0

24   4801    5000         NSR        100.0

25   5001    5200         NSR        100.0

26   5201    5400         NSR        100.0

27   5401    5600         NSR        100.0

28   5601    5800         NSR        100.0

29   5801    6000         NSR        100.0


查看完整回答
反对 回复 2022-12-20
?
德玛西亚99

TA贡献1770条经验 获得超3个赞

如果你的数据不是太大,你可以使用广播方式:


cond1 = df1.onset.values[:,None] >= df2.onset.values

cond2 = df1.offset.values[:,None] <= df2.offset.values


mask = (cond1&cond2)

idx = np.where(mask.any(1), mask.argmax(1), np.nan)


for col in ['rhythm_name', 'rhythm_code']:

    df1[col] = df2[col].reindex(idx).values

输出:


0       1     200         NSR        100.0

1     201     400         NSR        100.0

2     401     600         NSR        100.0

3     601     800         NSR        100.0

4     801    1000         NSR        100.0

5    1001    1200         NSR        100.0

6    1201    1400         NSR        100.0

7    1401    1600         NSR        100.0

8    1601    1800         NSR        100.0

9    1801    2000         NSR        100.0

10   2001    2200         NSR        100.0

11   2201    2400         NSR        100.0

12   2401    2600         NSR        100.0

13   2601    2800         NaN          NaN

14   2801    3000  JUNCTIONAL       4000.0

15   3001    3200  JUNCTIONAL       4000.0

16   3201    3400  JUNCTIONAL       4000.0

17   3401    3600  JUNCTIONAL       4000.0

18   3601    3800  JUNCTIONAL       4000.0

19   3801    4000         NaN          NaN

20   4001    4200         NSR        100.0

21   4201    4400         NSR        100.0

22   4401    4600         NSR        100.0

23   4601    4800         NSR        100.0

24   4801    5000         NSR        100.0

25   5001    5200         NSR        100.0

26   5201    5400         NSR        100.0

27   5401    5600         NSR        100.0

28   5601    5800         NSR        100.0

29   5801    6000         NSR        100.0

选项 2:另一种(更好的)方法merge_asof:


(pd.merge_asof(df1,df2,on='onset',direction='backward',suffixes=['','_y'])

   .query('offset<=offset_y')

   .reindex(df1.index)

   .drop('offset_y', axis=1)

   .fillna(df1)

)

你得到相同的输出。


查看完整回答
反对 回复 2022-12-20
  • 2 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信