簡體   English   中英

有條件地合並pd.DataFrames

[英]Conditionally merge pd.DataFrames

我想知道大熊貓是否有可能:

  • df2 ,我想創建new1new2
  • new1是從df1中找到的與A和B列匹配的最新日期。
  • new2是可以從df1中找到的,與列A匹配但與B匹配的最新日期。
  • 我設法得到new1但沒有得到new2

碼:

import pandas as pd

d1 = [['1/1/19', 'xy','p1','54'], ['1/1/19', 'ft','p2','20'], ['3/15/19', 'xy','p3','60'],['2/5/19', 'xy','p4','40']]

df1 = pd.DataFrame(d1, columns = ['Name', 'A','B','C']) 

d2 =[['12/1/19', 'xy','p1','110'], ['12/10/19', 'das','p10','60'], ['12/20/19', 'fas','p50','40']]

df2 = pd.DataFrame(d2, columns = ['Name', 'A','B','C'])

d3 = [['12/1/19', 'xy','p1','110','1/1/19','3/15/19'], ['12/10/19', 'das','p10','60','0','0'], ['12/20/19', 'fas','p50','40','0','0']]

dfresult = pd.DataFrame(d3, columns = ['Name', 'A','B','C','new1','new2']) 

更新!

您可以通過以下方式做到這一點:

  • 基於A的標准合並
  • 刪除所有與B值匹配的條目
  • 排序日期
  • 在A上刪除重復項,保留最后一個日期(nb假定日期采用日期格式,而不是字符串!)
  • 合並回id

從而:

source = df1.copy()  # renamed
v = df2.merge(source, on='A', how='left')  # get all values where df2.A == source.A
v = v[v['B_x'] != v['B_y']]  # drop entries where B values are the same
nv = v.sort_values(by=['Name_y']).drop_duplicates(subset=['Name_x'], keep='last')
df2.merge(nv[['Name_y', 'Name_x']].rename(columns={'Name_y': 'new2', 'Name_x': 'Name'}),
          on='Name', how='left')  # keeps non-matching, consider inner

這樣產生:

Out[94]: 
       Name    A    B    C     new2
0   12/1/19   xy   p1  110  3/15/19
1  12/10/19  das  p10   60      NaN
2  12/20/19  fas  p50   40      NaN

我最初的想法是做類似下面的事情。 可悲的是,它並不優雅。 通常,這種確定某些值的方法被人們普遍反對,因為它無法擴展且數據量很大,變得特別慢。

def find_date(row, source=df1):  # renamed df1 to source
    t = source[source['B'] != row['B']]
    t = t[t['A'] == row['A']]
    return t.sort_values(by='date', ascending=False).iloc[0]

df2['new2'] = df2.apply(find_date, axis=1)

IIUC,您想向df2添加兩列: new1new2

首先,我修改了兩件事:

df1 = pd.DataFrame(d1, columns = ['Name1', 'A','B','C']) 

df2 = pd.DataFrame(d2, columns = ['Name2', 'A','B','C'])

df1.Name1 = pd.to_datetime(df1.Name1)

為了易於使用,將Name1NameName1Name2 然后我將Name1轉換為實際日期,因此我們可以按組獲取最大日期。

然后,在A列上將df2與df1合並。 這將為我們提供與該列匹配的行

aux = df2.merge(df1, on='A')

然后,當兩個數據幀上的B列相同時,我們從中獲得Name1

df2['new1'] = df2.index.map(aux[aux.B_x==aux.B_y].Name1).fillna(0)

如果它們不同,我們將為每個A組獲得最長日期:

df2['new2'] = df2.A.map(aux[aux.B_x!=aux.B_y].groupby('A').Name1.max()).fillna(0)

輸出:

      Name2    A    B    C                 new1                 new2
0   12/1/19   xy   p1  110  2019-01-01 00:00:00  2019-03-15 00:00:00
1  12/10/19  das  p10   60                    0                    0
2  12/20/19  fas  p50   40                    0                    0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM