标题有点令人困惑,但我会尽力在这里解释我的问题.我有2个pandas数据帧,a和b:
>> print a
id | value
 1 | 250
 2 | 150
 3 | 350
 4 | 550
 5 | 450
>> print b
low | high | class
100 | 200  | 'A' 
200 | 300  | 'B' 
300 | 500  | 'A' 
500 | 600  | 'C' 
我想在表a中创建一个名为class的新列,该列包含符合表b的值的类.这是我想要的结果:
>> print a
id | value | class
 1 | 250   | 'B'
 2 | 150   | 'A'
 3 | 350   | 'A'
 4 | 550   | 'C'
 5 | 450   | 'A'
我编写了以下代码,它可以满足我的需求:
a['class'] = pd.Series()
for i in range(len(a)):
    val = a['value'][i]
    cl = (b['class'][ (b['low'] <= val) \
                      (b['high'] >= val) ].iat[0])
    a['class'].set_value(i,cl)
问题是,表格长度大约为10左右很快,但我试图用a和b的表格大小为100,000+.使用pandas中的某些函数/属性有更快的方法吗?
这是一种灵感来自@ piRSquared 解决方案的范围连接的方法:
A = a['value'].values
bh = b.high.values
bl = b.low.values
i, j = np.where((A[:, None] >= bl) & (A[:, None] <= bh))
pd.DataFrame(
    np.column_stack([a.values[i], b.values[j]]),
    columns=a.columns.append(b.columns)
)
输出:
  id value  low high  class
0  1   250  200  300   'B' 
1  2   150  100  200   'A' 
2  3   350  300  500   'A' 
3  4   550  500  600   'C' 
4  5   450  300  500   'A'
诚然,这是一个不如使用 Series.searchsorted 优雅的解决方案,但它运行速度非常快!
我从 pandas DataFrame 中提取数据并将它们转换为列表,然后使用 np.where 填充一个名为“aclass”的变量,其中条件得到满足(暴力循环)。然后我将“aclass”写入原始数据框a。
评估时间为 0.07489705 秒,所以即使有 200,000 个数据点,它也相当快!
# create 200,000 fake a data points
avalue = 100+600*np.random.random(200000) # assuming you extracted this from a with avalue = np.array(a['value'])
blow = [100,200,300,500] # assuming you extracted this from b with list(b['low'])
bhigh = [200,300,500,600] # assuming you extracted this from b with list(b['high'])
bclass = ['A','B','A','C'] # assuming you extracted this from b with list(b['class'])
aclass = [[]]*len(avalue) # initialize aclass
start_time = time.time() # this is just for timing the execution
for i in range(len(blow)):
    for j in np.where((avalue>=blow[i]) & (avalue<=bhigh[i]))[0]:
        aclass[j]=bclass[i]
# add the class column to the original a DataFrame
a['class'] = aclass
print("--- %s seconds ---" % np.round(time.time() - start_time,decimals = 8))
| 归档时间: | 
 | 
| 查看次数: | 1337 次 | 
| 最近记录: |