在多个条件下合并多个数据帧中的数据

2024-10-03 13:20:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我想合并多个数据帧,但前提是键匹配并且日期范围在df1中的“initialaccept”日期范围的90天之内。我希望保留df1中的所有行,只合并df2、df3等中的其他行,只要它们与键匹配并且在日期范围内。在

注意:先合并dfs然后再考虑日期范围条件对我不起作用。我第一次使用这个方法,但是在很多情况下合并是成功的,但是由于日期范围超出了限制,我让脚本删除了行。我需要以某种方式保留df1中的所有行。在

Python Pandas: Merging data frames on multiple conditions-这个问题类似,但它似乎是合并然后应用条件。我认为更好的方法是应用条件,然后在条件满足时合并。不过,我愿意接受建议。在

数据帧:

a = {'Key': [100000204, 100000255, 100000271,100000286,100000628], 
 'InitialAdmit': ['2012-06-04', '2012-05-03', '2012-01-16', '2012-10-26', '2012-02-21'],
 '90DayRange': ['2012-09-02', '2012-08-01', '2012-04-15', '2013-01-24', '2012-05-21']
}
df1 = pandas.DataFrame(data=a)
df1


b = {'Key': [100000208, 100000255, 100000723,100000286,100000866], 
 'InitialAdmit': ['2012-01-22', '2012-06-03', '2012-10-26', '2012-11-26', '2012-05-11'],
}
df2 = pandas.DataFrame(data=b)
df2 

c = {'Key': [100000255, 100000255, 100000702,100000221,100000628], 
 'InitialAdmit': ['2012-06-22', '2012-10-03', '2012-10-26', '2012-11-26', '2012-04-11'],
}
df3 = pandas.DataFrame(data=c)
df3

脚本:

^{pr2}$

Tags: 数据方法key脚本dataframepandasdata条件
2条回答

我仍然推荐merge-then-filter,这里我们使用Boolean索引和combine_first

df=df1.merge(df2,on='Key')
m=(df.InitialAdmit_y>=df.InitialAdmit_x)&(df.InitialAdmit_y<=df.InitialAdmit_x)
df1.set_index('Key').combine_first(df[m].set_index('Key'))


Out[215]: 
          90DayRange InitialAdmit InitialAdmit_x InitialAdmit_y
Key                                                            
100000204 2012-09-02   2012-06-04            NaT            NaT
100000255 2012-08-01   2012-05-03     2012-05-03     2012-06-03
100000271 2012-04-15   2012-01-16            NaT            NaT
100000286 2013-01-24   2012-10-26     2012-10-26     2012-11-26
100000628 2012-05-21   2012-02-21            NaT            NaT

考虑使用左连接的链式合并的reduce。下面用3份df2的副本演示。另外,下面假设initialaccept是数据帧的最后一列。根据需要重新排序。在

import pandas 
import numpy
from functools import reduce    
...

# LIST OF DATAFRAMES WITH SUFFIXING OF INITIALADMIT TO AVOID NAME COLLISION
dfList = [d.rename(columns={'InitialAdmit':'InitialAdmit_' + str(i)}) 
          for i,d  in enumerate([df1, df2, df2, df2])]

# USER-DEFINED METHOD CONDITIONING ON LAST COLUMN
def mergefilter(x, y):
    tmp = pandas.merge(x, y, on='Key', how='left')
    tmp.loc[~(tmp.iloc[:, -1].between(tmp['InitialAdmit_0'], tmp['90DayRange'])), 
            tmp.columns[-1]] = numpy.nan

    return tmp

finaldf = reduce(mergefilter, dfList)

print(finaldf)
#    90DayRange InitialAdmit_0        Key InitialAdmit_1 InitialAdmit_2 InitialAdmit_3
# 0  2012-09-02     2012-06-04  100000204            NaN            NaN            NaN
# 1  2012-08-01     2012-05-03  100000255     2012-06-03     2012-06-03     2012-06-03
# 2  2012-04-15     2012-01-16  100000271            NaN            NaN            NaN
# 3  2013-01-24     2012-10-26  100000286     2012-11-26     2012-11-26     2012-11-26
# 4  2012-05-21     2012-02-21  100000628            NaN            NaN            NaN

相关问题 更多 >