簡體   English   中英

比較一列中的值是否在另一列python pandas中的兩個值之間

[英]compare whether value in one column is between two values in another column python pandas

我有兩個數據框如下:

A = pd.DataFrame({"value":[3, 7, 5 ,18,23,27,21,29]})

B = pd.DataFrame({"low":[1, 6, 11 ,16,21,26], "high":[5,10,15,20,25,30], "name":["one","two","three","four","five", "six"]})

我想知道A中的“值”是否在B中的“高”和“低”之間,如果是,我想將列名從B復制到A.

輸出應如下所示:

A = pd.DataFrame({"value":[3, 7, 5 ,18,23,27,21,29], "name":["one","two","one","four","five", "six", "five", "six"]})

我的函數使用iterrows如下:

def func1(row):
    x = row['value']
    for index,value in B.iterrows():
        if ((value['low'] <= x) &(x<=value['high'])):
            return value['name']

但它還沒有實現我想做的事情,

謝謝,

您可以使用列表推導來迭代A的值,然后使用loc來獲取相關的映射值。 le小於或等於,且ge大於或等於。

例如,第一行中v = 3 使用簡單的布爾索引:

>>> B[(B['low'].le(v)) & (B['high'].ge(v))]
   high  low name
0     5    1  one

假設DataFrame B沒有任何重疊范圍,那么您將返回上面的一行。 然后使用loc獲取name列,如下所示。 因為每個返回的名稱都是一個系列,所以您需要獲取第一個和唯一的標量值(例如,使用iat )。

A['name'] = [B.loc[(B['low'].le(v)) & (B['high'].ge(v)), 'name'].iat[0] 
             for v in A['value']]

>>> A
   value  name
0      3   one
1      7   two
2      5   one
3     18  four
4     23  five
5     27   six
6     21  five
7     29   six

我相信你正在尋找這樣的東西:

In [1]: import pandas as pd

In [2]: A = pd.DataFrame({"value":[3, 7, 5 ,18,23,27,21,29]})

In [3]: 

In [3]: B = pd.DataFrame({"low":[1, 6, 11 ,16,21,26], "high":[5,10,15,20,25,30], "name":["one","two","three","four","five", "six"]})

In [4]: A
Out[4]: 
   value
0      3
1      7
2      5
3     18
4     23
5     27
6     21
7     29

In [5]: B
Out[5]: 
   high  low   name
0     5    1    one
1    10    6    two
2    15   11  three
3    20   16   four
4    25   21   five
5    30   26    six

In [6]: def func1(x):
   ...:     for row in B.itertuples():
   ...:         if row.low <= x <= row.high:
   ...:             return row.name
   ...:         

In [7]: A.value.map(func1)
Out[7]: 
0     one
1     two
2     one
3    four
4    five
5     six
6    five
7     six
Name: value, dtype: object

In [8]: A['name'] = A['value'].map(func1)

In [9]: A
Out[9]: 
   value  name
0      3   one
1      7   two
2      5   one
3     18  four
4     23  five
5     27   six
6     21  five
7     29   six

我使用itertuples因為它應該快一點,但一般來說這不會非常有效。 這是一個解決方案,但可能會有更好的解決方案。

編輯添加:

In [8]: timeit A['value'].map(func1)
100 loops, best of 3: 10.5 ms per loop

In [9]: timeit [B.loc[(B['low'].le(v)) & (B['high'].ge(v)), 'name'].tolist()[0] for v in A['value']]
100 loops, best of 3: 9.06 ms per loop

快速而骯臟的測試表明Alexander的方法更快。 我想知道它是如何擴展的。

暫無
暫無

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

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