Python 基于条件合并数据帧

Python 基于条件合并数据帧,python,pandas,dataframe,Python,Pandas,Dataframe,我有两个文件,显示有关产品交易的信息 第1类业务 d_op_1 = pd.DataFrame({'id':[1,1,1,2,2,2,3,3],'cost':[10,20,20,20,10,20,20,20], 'date':[2000,2006,2012,2000,2009,2009,2002,2006]}) 第2类业务 d_op_2 = pd.DataFrame({'id':[1,1,2,2,3,4,5,5],'cost':[3000,3100

我有两个文件,显示有关产品交易的信息

第1类业务

d_op_1 = pd.DataFrame({'id':[1,1,1,2,2,2,3,3],'cost':[10,20,20,20,10,20,20,20],
                       'date':[2000,2006,2012,2000,2009,2009,2002,2006]})

第2类业务

d_op_2 = pd.DataFrame({'id':[1,1,2,2,3,4,5,5],'cost':[3000,3100,3200,4000,4200,3400,2000,2500],
                       'date':[2010,2015,2008,2010,2006,2010,1990,2000]})

我只想保留那些寄存器,如果在两个类型2的操作之间有类型1的操作。 例如,对于id为“1”的产品,在两次类型2(20102015)的操作之间有一次类型1(2012)的操作,因此我希望保留该记录

所需的输出可能是:

或者这个:

使用pd.merge()我得到了以下结果:

我如何过滤这个以获得所需的输出

您可以使用:

#concat DataFrames together             
df4 = pd.concat([d_op_1.rename(columns={'cost':'cost1'}), 
                 d_op_2.rename(columns={'cost':'cost2'})]).fillna(0).astype(int)

#print (df4)

#find max and min dates per goups
df3 = d_op_2.groupby('id')['date'].agg({'start':'min','end':'max'}) 
#print (df3)

#join max and min dates to concated df
df = df4.join(df3, on='id')
df = df[(df.date > df.start) & (df.date < df.end)]
#reshape df for min, max and dated between them
df = pd.melt(df, 
             id_vars=['id','cost1'], 
             value_vars=['date','start','end'], 
             value_name='date')
#remove columns
df = df.drop(['cost1','variable'], axis=1) \
       .drop_duplicates()
#merge to original, sorting
df = pd.merge(df, df4, on=['id', 'date']) \
       .sort_values(['id','date']).reset_index(drop=True)
#reorder columns
df = df[['id','cost1','cost2','date']]

大多数人不会输入您提供的所有图片数据。如果提供可以快速剪切和粘贴的数据,问题通常更容易回答。@jezrael谢谢,你说得对。我纠正了it@StephenRauch谢谢,数据added@jezrael我想每年只有一排,但你是对的,那可能会有更大的问题。使用两行也可以。
print (df)
   id  cost1  cost2  date
0   1      0   3000  2010
1   1     20      0  2012
2   1      0   3100  2015
3   2      0   3200  2008
4   2     10      0  2009
5   2     20      0  2009
6   2      0   4000  2010

#if need lists for duplicates
df = df.groupby(['id','cost2', 'date'])['cost1'] \
       .apply(lambda x: list(x) if len(x) > 1 else x.values[0]) \
       .reset_index()
df = df[['id','cost1','cost2','date']]
print (df)
   id     cost1  cost2  date
0   1        20      0  2012
1   1         0   3000  2010
2   1         0   3100  2015
3   2  [10, 20]      0  2009
4   2         0   3200  2008
5   2         0   4000  2010