![](/img/trans.png)
[英]Python Pandas: Check whether a value in one column is present in subsets of rows in another column
[英]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.