【问题标题】:Pandas DataFrame filter rows using another DataFrame ColumnPandas DataFrame 使用另一个 DataFrame 列过滤行
【发布时间】:2020-09-18 09:11:01
【问题描述】:
import pandas as pd
import numpy as np

dict1 = {'col1': ['A', 'A', 'A', 'A', 'A','B', 'B', 'B', 'B', 'B' ], 
       'col2':[2, 2, 2, 3, 3, 2, 2, 3, 3 , 3], 
       'col3':[0.7, 0.8, 0.9, 0.95, 0.85, 0.65, 0.75, 0.45, 0.55, 0.75 ],
       'col4':[100,200,300,400,500,600,700,800,900,1000]}
df1 = pd.DataFrame(data=dict1)
df1

dict2 = {'col1': ['A', 'B' ], 
       'col2':[0.75, 0.65], 
       'col3':[1000, 2000 ],
       'col4':[0.8, 0.9]}
df2 = pd.DataFrame(data=dict2)
df2

以最快的方式如何使用 df2 过滤 df1,取决于 df1['col3'] >= df2['col2'] 是否相等 col1s?

预期结果

>>> df1
  col1  col2  col3  col4
1    A     2  0.80   200
2    A     2  0.90   300
3    A     3  0.95   400
4    A     3  0.85   500
5    B     2  0.65   600
6    B     2  0.75   700
9    B     3  0.75  1000

我的尝试给出了以下错误

>>> df1= df1[df1['col3'] >= float(df2[df2['col1']==df1['col1']]['col2'].values[0])]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/burcak/anaconda3/lib/python3.7/site-packages/pandas/core/ops/common.py", line 64, in new_method
    return method(self, other)
  File "/home/burcak/anaconda3/lib/python3.7/site-packages/pandas/core/ops/__init__.py", line 521, in wrapper
    raise ValueError("Can only compare identically-labeled Series objects")
ValueError: Can only compare identically-labeled Series objects

【问题讨论】:

  • 恭喜您提出pandas 问题170,000! @Burcak 你刚刚赢得了一辆新车! ;)

标签: python pandas dataframe


【解决方案1】:

我会做merge

out = df1.merge(df2[['col1','col2']], on = 'col1', suffixes = ('','1')).query('col3>=col21').drop('col21',1)

out
Out[15]: 
  col1  col2  col3  col4
1    A     2  0.80   200
2    A     2  0.90   300
3    A     3  0.95   400
4    A     3  0.85   500
5    B     2  0.65   600
6    B     2  0.75   700
9    B     3  0.75  1000

reindex

out = df1[df1['col3'] >= df2.set_index('col1')['col2'].reindex(df1['col1']).values]
Out[19]: 
  col1  col2  col3  col4
1    A     2  0.80   200
2    A     2  0.90   300
3    A     3  0.95   400
4    A     3  0.85   500
5    B     2  0.65   600
6    B     2  0.75   700
9    B     3  0.75  1000

你也可以使用map:

 df1.loc[df1.col3 >= df1.col1.map(df2.set_index("col1").col2)]

【讨论】:

  • 这个col21是怎么生成的?
  • @burcak df1.merge(df2[['col1','col2']], on = 'col1', suffixes = ('','1')) 看后缀~如果重复列会在末尾添加str
  • 我的目标是减少运行时间
  • @burcak 我们提供多种解决方案,您可以检查哪个更好,然后我建议使用 map 或重新索引
  • 是的,我为它们计时,地图解决方案提供了最佳运行时间。谢谢@BEN_YO
【解决方案2】:

我的方法类似于@Ben_Yo 的合并答案,但代码行更多,但可能更简单一些。

你只是:

  1. 合并列并创建新数据框s
  2. 将数据名s更改为布尔系列,根据条件返回TrueFalse,在本例中为s['col3'] &gt;= s['col2']
  3. 最后,将s 传递给df1,结果将排除布尔系列s 中返回False 的行:

s = pd.merge(df1[['col1', 'col3']], df2[['col1', 'col2']], how='left', on='col1')
s = s['col3'] >= s['col2']
df1[s]
Out[1]: 
  col1  col2  col3  col4
1    A     2  0.80   200
2    A     2  0.90   300
3    A     3  0.95   400
4    A     3  0.85   500
5    B     2  0.65   600
6    B     2  0.75   700
9    B     3  0.75  1000

【讨论】:

    猜你喜欢
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多