【问题标题】:Pandas merge and keep right and delete left熊猫合并并保持右和删除左
【发布时间】:2019-03-18 06:24:57
【问题描述】:

我有一个周五所有证券的价目表。一些证券在周六和周五保持相同的价格。我想复制周五到周六的价格,以获取不在周六列出的证券价格。

我尝试使用 pandas merge 来完成这项任务,如下所示。

我将Indicator 设置为True,如下所示为两个数据框加入True

# df_friday has 10 securities
# df _saturday has 3 securities
merge_df=pd.merge(df_friday,df_saturday,on='security',how="outer",indicator=True)

merge_df = merge_df[merge_df['_merge']=='left_only']
merge_df =merge_df.drop(['price_y','_merge'],axis=1)
merge_df = merge_df.rename(columns = {'price_x':'price'})

df_saturday = pd.concat([df_saturday,merge_df],ignore_index=True)

我的两个数据框的列是一样的,

Columns: [security, price]

我做对了吗?或者我可以用一种简单的方式做到这一点吗?

例如,

# df_friday
  security price
1 apple    35.25
2 reliance  25.5
3 samsung   12.5
4 tata      28.5
5 sony      30.2

# df_saturday
  security price
1 reliance  26.8
2 samsung   11.2

# df_saturday_result should be as follows,
  security price
1 reliance  26.8
2 samsung   11.2
3 apple    35.25
4 tata      28.5
5 sony      30.2

【问题讨论】:

  • 你能添加一些样本数据来质疑预期的输出吗?

标签: python pandas dataframe merge


【解决方案1】:

我觉得你可以的

df_saturday = df_saturday.merge(df_friday, how='outer', on=['security','price']).drop_duplicates(['security'], keep='first')

print(df_saturday)

输出:

   price    security                                                                                                                    
0  26.80  reliance                                                                                                                    
1  11.20   samsung                                                                                                                    
2  35.25     apple                                                                                                                    
5  28.50      tata                                                                                                                    
6  30.20      sony

【讨论】:

  • 熊猫合并是否遵守顺序?即df_saturday的元素会先出现吗?
  • 是的,它保持订单。 df_saturday 元素将首先出现,然后是 df_friday
  • 您可以在 drop_duplicates() 中使用 keep='first' 使其明确。当然,默认是keep='first',但是指定它会提高可读性。
  • @AsishM。感谢你的提问。我心里也有这个疑问。这就是我使用我在那个问题中提到的方法的原因。
  • @Akshay 和 RebornCodeLover:谢谢。我不知道财产保留。
【解决方案2】:

对其他答案中提到的 3 种方法进行了一些时间检查。

fri =pd.DataFrame (columns =['security', 'price'], index = range(3), data =[['a',2],['b',4],['c',6]] )
sat =pd.DataFrame (columns =['security', 'price'], index = range(2), data =[['a',3],['c',5]] )
In [90]: %timeit out = sat.merge(fri, how='outer', on=['security', 'price']).drop_duplicates()
5.19 ms ± 150 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [91]: %timeit result_1 = pd.concat([sat,fri],ignore_index=True).drop_duplicates(subset=['security'], keep='first')
1.82 ms ± 26.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [92]: %timeit result_2 = pd.concat([sat, fri[~fri.security.isin(sat.security)]], ignore_index=True)
1.19 ms ± 113 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [93]: %timeit out = sat.merge(fri, how='outer', on=['security', 'price']).drop_duplicates()
5.02 ms ± 181 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

看起来过滤然后连接是最快的,而连接然后重复数据删除也不算太糟糕。相比之下,合并相当慢。

【讨论】:

    【解决方案3】:

    你也可以使用 pandas.concat():

    代码:

    import pandas as pd
    
    fri =pd.DataFrame (columns =['security', 'price'], index = range(3), data =[['a',2],['b',4],['c',6]] )
    sat =pd.DataFrame (columns =['security', 'price'], index = range(2), data =[['a',3],['c',5]] )
    print ('TEST DATA:')
    print (fri)
    print (sat)
    
    print ('\nSOLUTION 1: concatenate and eliminate duplicates')
    result_1 = pd.concat([sat,fri],ignore_index=True).drop_duplicates(subset=['security'], keep='first')
    print (result_1)
    
    print ('\nSOLUTION 2: filter unique and then concatenate')
    fri_unique = fri[~fri.security.isin(sat.security)]
    result_2 = pd.concat([sat, fri_unique], ignore_index=True)
    print (result_2)
    

    输出:

    TEST DATA:
      security  price
    0        a      2
    1        b      4
    2        c      6
      security  price
    0        a      3
    1        c      5
    
    SOLUTION 1: concatenate and eliminate duplicates
      security  price
    0        a      3
    1        c      5
    3        b      4
    
    SOLUTION 2: filter unique and then concatenate
      security  price
    0        a      3
    1        c      5
    2        b      4
    

    【讨论】:

    • 感谢您的回答。所以 concat 和 external merge 做同样的事情。我说的对吗?
    • 两种方式都应该给出相同的结果。选择在您的上下文中更快、更易读的任何内容。 Python 中通常有不止一种方式。
    猜你喜欢
    • 2023-01-04
    • 1970-01-01
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多