Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫中的复杂条件连接_Python_Pandas_Dataframe_Join_Merge - Fatal编程技术网

Python 熊猫中的复杂条件连接

Python 熊猫中的复杂条件连接,python,pandas,dataframe,join,merge,Python,Pandas,Dataframe,Join,Merge,我想根据复杂的条件连接/合并两个数据帧(具有不同的记录)。条件类似于: merge rows where df1_row['termination_date'] - df2_row['creation_date'] < pd.Timedelta(n) and df1_row['termination_date'] - df2_row['creation_date'] > pd.Timedelta(-k) and df1_row['smth1'] == df2_row['smth1']

我想根据复杂的条件连接/合并两个数据帧(具有不同的记录)。条件类似于:

merge rows where
df1_row['termination_date'] - df2_row['creation_date'] < pd.Timedelta(n)
and df1_row['termination_date'] - df2_row['creation_date'] > pd.Timedelta(-k)
and df1_row['smth1'] == df2_row['smth1']
and df1_row['smth2'] != df2_row['smth2']
...
合并行,其中
df1_行['termination_date']-df2_行['creation_date']pd.Timedelta(-k)
和df1_行['smth1']==df2_行['smth1']
和df1_行['smth2']!=df2_行['smth2']
...
在PostgresSQL中,可以非常简单地编写:

df1 join df2
on age(df1.creation_date, df2.termination_date) < interval '...'
and age(df1.creation_date, df2.termination_date) > interval '...'
and df1.smth1 = df2.smth1
...
df1连接df2
在年龄(df1.创建日期,df2.终止日期)<间隔'…'
和年龄(df1.创建日期,df2.终止日期)>间隔“…”
和df1.smth1=df2.smth1
...

但熊猫中不允许这种条件连接。使用python和pandas实现这种逻辑有什么最佳实践/最佳方法吗?

确实不是很直截了当。我将逐行检查dataframe 1,并在dataframe 2中找到合适的匹配项(基于标准)。如果有多个候选者,您必须决定如何选择最好的一个(可能只是第一个匹配),然后将匹配与原始行合并

随机导入
进口大熊猫
导入日期时间
#生成一些测试数据帧
df_1=pandas.DataFrame([{
“终止日期”:datetime.datetime.fromtimestamp(random.randint(16058659191911606297560)),
“创建日期”:datetime.datetime.fromtimestamp(random.randint(16058659191911606297560)),
“smth1”:random.randint(0,1),
“smth2”:random.randint(0,1),
}适用于uu范围内(1000)])
df_2=pandas.DataFrame([{
“终止日期”:datetime.datetime.fromtimestamp(random.randint(16058659191911606297560)),
“创建日期”:datetime.datetime.fromtimestamp(random.randint(16058659191911606297560)),
“smth1”:random.randint(0,1),
“smth2”:random.randint(0,1),
}适用于uu范围内(1000)])
def try_to_join(行:pandas.Series,其他:pandas.DataFrame,后缀:str=“_right”)->pandas.Series:
“”“尝试基于复杂条件加入。
Args:
行(pandas.Series):要加入的行(左)
其他(pandas.DataFrame):要加入的数据帧(右)
后缀(str,可选):将放在“其他”列上的后缀。默认为“\u right”。
返回:
熊猫系列:加入的系列
"""
#定义条件
条件1=行[“终止日期”]-其他[“创建日期”]pandas.Timedelta(-24,unit=“H”)
条件_3=行[“smth1”]==其他[“smth1”]
条件4=行[“smth2”]!=其他[“smth2”]
#在“其他”中找到满足条件的行
matches=other.loc[条件1和条件2和条件3和条件4,:]
#如果未找到匹配项,则返回原始行
如果匹配。形状[0]==0:
返回行
#TODO:决定如何处理多个匹配(现在选择第一个匹配)
match=matches.iloc[0]
#在“其他”列中添加后缀
match.index=[f“{col}{suffix}”表示match.index中的列]
#将匹配项中的字段添加到原始行
对于match.index中的列:
行[col]=匹配[col]
#返回新行
返回行
#使用上面的函数将2个数据帧连接到一个新的数据帧中
df_join=df_1.应用(lambda行:try_to_join(行,其他=df_2),轴=1)
输出:

creation\u date creation\u date\u right smth1 smth1\u right smth2\
0   2020-11-24 02:10:35 2020-11-24 07:08:40      1          1.0      0   
112020-11-2123:46:28 NaT 0南1
2   2020-11-22 21:54:58 2020-11-22 13:27:57      0          0.0      0   
3   2020-11-23 18:45:59 2020-11-20 22:58:10      1          1.0      0   
4   2020-11-20 13:24:18 2020-11-23 06:18:23      1          1.0      0   
..                  ...                 ...    ...          ...    ...   
995 2020-11-25 10:40:19 2020-11-24 07:08:40      1          1.0      0   
996 2020-11-24 19:27:47 2020-11-24 23:21:32      0          0.0      0   
997 2020-11-23 10:18:30 2020-11-24 07:08:40      1          1.0      0   
998 2020-11-20 15:54:53 2020-11-24 23:21:32      0          0.0      0   
999 2020-11-22 14:19:45 2020-11-24 23:21:32      0          0.0      0   
smth2 \u权利终止\u日期终止\u日期\u权利
0            1.0 2020-11-25 01:59:37    2020-11-22 03:38:51  
1 NaN 2020-11-23 22:55:26 NaT
2            1.0 2020-11-22 12:47:03    2020-11-24 12:32:50  
3            1.0 2020-11-21 18:49:48    2020-11-22 16:16:23  
4            1.0 2020-11-22 12:10:14    2020-11-24 00:58:23  
..           ...                 ...                    ...  
995          1.0 2020-11-23 08:04:51    2020-11-22 03:38:51  
996          1.0 2020-11-24 09:48:11    2020-11-23 13:43:11  
997          1.0 2020-11-24 06:45:34    2020-11-22 03:38:51  
998          1.0 2020-11-25 02:19:43    2020-11-23 13:43:11  
999          1.0 2020-11-25 09:41:06    2020-11-23 13:43:11  
[1000行x 8列]

您会注意到,当没有找到匹配项时,
\u right
的字段将为空。

确实不是很直接。我将逐行检查dataframe 1,并在dataframe 2中找到合适的匹配项(基于标准)。如果有多个候选者,您必须决定如何选择最好的一个(可能只是第一个匹配),然后将匹配与原始行合并

随机导入
进口大熊猫
导入日期时间
#生成一些测试数据帧
df_1=pandas.DataFrame([{
“终止日期”:datetime.datetime.fromtimestamp(random.randint(16058659191911606297560)),
“创建日期”:datetime.datetime.fromtimestamp(random.randint(16058659191911606297560)),
“smth1”:random.randint(0,1),
“smth2”:random.randint(0,1),
}适用于uu范围内(1000)])
df_2=pandas.DataFrame([{
“终止日期”:datetime.datetime.fromtimestamp(random.randint(1605865919,16