简体   繁体   中英

Merging Pandas Dataframes on Multiple Conditions

I am trying to merge Frame A to Frame B on the size asset life conditions specified in Frame B using pandas. I have tried both the merge and mergeasof commands but have not found a solution.

Frame A:

ID Material Size
0 A 9
1 B 21
2 B 14

Frame B: note (size specifies asset life)

Material Size < 10 10 < Size < 20 Size > 20
A 5 10 20
B 1 5 10

To form Frame C:

ID Material Asset Life
0 A 5
1 B 10
2 B 5

The the first step is to normalize DataFrame B and end up with the following:

Material,LoweBound,UpperBound,AssetLife
A,0,10,5
A,10,20,10
A,20,np.Inf,20
B,0,10,1
B,10,20,5
B,20,np.Inf,10

Now a simple join should do the trick.

# step1: set_index('Material') and stack frameB dfB.columns = ['Material', 'Size <= 10', '10 < Size <= 20', 'Size > 20'] obj_size_map = dfB.set_index('Material').stack() # print(obj_size_map) # Material # A Size <= 10 5 # 10 < Size <= 20 10 # Size > 20 20 # B Size <= 10 1 # 10 < Size <= 20 5 # Size > 20 10 # dtype: int64 # step2. use pd.cut to create a size_tag for frame A, with frameB's columns as labels dfA['size_tag'] = pd.cut(dfA.Size, bins=[-np.inf, 10, 20, np.inf], labels=dfB.columns[1:]) # print(dfA) # ID Material Size size_tag # 0 0 A 9 Size <= 10 # 1 1 B 21 Size > 20 # 2 2 B 14 10 < Size <= 20 # step3. use pandas DF's index to assign a new columns dfC = dfA.set_index(['Material', 'tag']) dfC['Asset Life'] = obj_size_map # print(dfC) # ID Size size_tag Asset Life # Material tag # A Size <= 10 0 9 Size <= 10 5 # B Size > 20 1 21 Size > 20 10 # 10 < Size <= 20 2 14 10 < Size <= 20 5 # step4. output result = dfC.reset_index()[['ID', 'Material', 'Asset Life']] # print(result) # ID Material Asset Life # 0 0 A 5 # 1 1 B 10 # 2 2 B 5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM