我有dataframe A
ip_address
0 13
1 5
2 20
3 11
.. ........
和另一个dataframe B
lowerbound_ip_address upperbound_ip_address country
0 0 10 Australia
1 11 20 China
基于此我需要在A
中添加一列
ip_address country
13 China
5 Australia
我有一个想法,我应该编写定义一个函数,然后在A的每一行调用map。但是我如何搜索B的每一行呢。有一个更好的方法吗。
答案 0 :(得分:9)
In [2503]: s = pd.IntervalIndex.from_arrays(dfb.lowerbound_ip_address,
dfb.upperbound_ip_address, 'both')
In [2504]: dfa.assign(country=dfb.set_index(s).loc[dfa.ip_address].country.values)
Out[2504]:
ip_address country
0 13 China
1 5 Australia
2 20 China
3 11 China
详细
In [2505]: s
Out[2505]:
IntervalIndex([[0, 10], [11, 20]]
closed='both',
dtype='interval[int64]')
In [2507]: dfb.set_index(s)
Out[2507]:
lowerbound_ip_address upperbound_ip_address country
[0, 10] 0 10 Australia
[11, 20] 11 20 China
In [2506]: dfb.set_index(s).loc[dfa.ip_address]
Out[2506]:
lowerbound_ip_address upperbound_ip_address country
[11, 20] 11 20 China
[0, 10] 0 10 Australia
[11, 20] 11 20 China
[11, 20] 11 20 China
设置
In [2508]: dfa
Out[2508]:
ip_address
0 13
1 5
2 20
3 11
In [2509]: dfb
Out[2509]:
lowerbound_ip_address upperbound_ip_address country
0 0 10 Australia
1 11 20 China
答案 1 :(得分:2)
df['lowerbound_ip_address']=df['ip_address']
pd.merge_asof(df1,df,on='lowerbound_ip_address',direction ='forward',allow_exact_matches =False)
Out[811]:
lowerbound_ip_address upperbound_ip_address country ip_address
0 0 10 Australia 5
1 11 20 China 13
答案 2 :(得分:2)
IntervalIndex与pandas 0.20.0相同,而@JohnGalt使用它的解决方案非常出色。
在该版本之前,此解决方案可以在整个范围内按国家/地区扩展IP地址。
df_ip = pd.concat([pd.DataFrame(
{'ip_address': range(row['lowerbound_ip_address'], row['upperbound_ip_address'] + 1),
'country': row['country']})
for _, row in dfb.iterrows()]).set_index('ip_address')
>>> dfa.set_index('ip_address').join(df_ip)
country
ip_address
13 China
5 Australia
20 China
11 China