Python 将查找表应用于存储箱或范围的数据帧
我有一个如下所示的数据框。假设这些是销售人员列表的销售额 此外,我还有一个查找表,其中包含按美元计算的佣金金额。这看起来像下图。因此,$0-$50000=5%,$50001-$250000=4%,等等 我要做的是将查找表应用于sales表,以生成下面的数据帧 尝试1:Python 将查找表应用于存储箱或范围的数据帧,python,python-3.x,pandas,Python,Python 3.x,Pandas,我有一个如下所示的数据框。假设这些是销售人员列表的销售额 此外,我还有一个查找表,其中包含按美元计算的佣金金额。这看起来像下图。因此,$0-$50000=5%,$50001-$250000=4%,等等 我要做的是将查找表应用于sales表,以生成下面的数据帧 尝试1: In [66]: a Out[66]: Sales_1 Sales_2 Sales_3 0 200000 300000 100000 1 100000 500000 500000 2
In [66]: a
Out[66]:
Sales_1 Sales_2 Sales_3
0 200000 300000 100000
1 100000 500000 500000
2 400000 1000000 200000
In [67]: b
Out[67]:
Commission
Sales
50000 0.05
250000 0.04
750000 0.03
9999999999 0.02
In [68]: c = b['Commission'][a <= b.index.values]
Traceback (most recent call last):
File "<ipython-input-68-d229bce29f01>", line 1, in <module>
c = b['Commission'][a <= b.index.values]
File "C:\WinPython64bit\python-3.5.2.amd64\lib\site-packages\pandas\core\ops.py", line 1184, in f
res = self._combine_const(other, func, raise_on_error=False)
File "C:\WinPython64bit\python-3.5.2.amd64\lib\site-packages\pandas\core\frame.py", line 3555, in _combine_const
raise_on_error=raise_on_error)
File "C:\WinPython64bit\python-3.5.2.amd64\lib\site-packages\pandas\core\internals.py", line 2911, in eval
return self.apply('eval', **kwargs)
File "C:\WinPython64bit\python-3.5.2.amd64\lib\site-packages\pandas\core\internals.py", line 2890, in apply
applied = getattr(b, f)(**kwargs)
File "C:\WinPython64bit\python-3.5.2.amd64\lib\site-packages\pandas\core\internals.py", line 1132, in eval
result = get_result(other)
File "C:\WinPython64bit\python-3.5.2.amd64\lib\site-packages\pandas\core\internals.py", line 1103, in get_result
result = func(values, other)
ValueError: operands could not be broadcast together with shapes (3,3) (4,)
[66]中的:a
出[66]:
销售1销售2销售3
0 200000 300000 100000
1 100000 500000 500000
2 400000 1000000 200000
在[67]中:
出[67]:
委员会
销售额
50000 0.05
250000 0.04
750000 0.03
9999999999 0.02
在[68]中:c=b[佣金][a要使用范围,pd.cut
是您的朋友。根据您当前的b
数据框架,您只需修改作为参数传递的箱子列表,以定义最低范围。这里我将0作为负销售不存在,但如果需要,您也可以使用任何负数,甚至可以处理-np.inf
和np。inf
而不是1E14
用于您的上下边界:
pd.cut(a.stack(), [0] + b.Sales.tolist(), labels=b.Commission).unstack()
Out[39]:
Sales_1 Sales_2 Sales_3
0 0.04 0.03 0.04
1 0.04 0.03 0.03
2 0.03 0.02 0.04
我发现b
像下面这样的更清晰,可以与cut一起使用:
Sales Commission
0 -inf NaN
1 50000 0.05
2 250000 0.04
3 750000 0.03
4 inf 0.02
论点变成:
pd.cut(a.stack(), b.Sales, labels=b.Commission[1:]).unstack()
@Boud已经击中了公园外的这一个。但这是我的拍摄
numpy
使用searchsorted
pd.DataFrame(
b.Commission.values[
b.index.values.searchsorted(a.values.ravel())
].reshape(a.values.shape),
a.index, a.columns)
Sales_1 Sales_2 Sales_3
0 0.04 0.03 0.04
1 0.04 0.03 0.03
2 0.03 0.02 0.04
pandas
使用
我还将堆叠a
,并移动边界定义
a_ = a.stack().sort_values().to_frame('Sales')
b_ = pd.DataFrame(dict(
Sales=np.append(0, b.index[:-1]),
Commissions=b.Commission.values
))
print(a_)
print()
print(b_)
Sales
0 Sales_3 100000
1 Sales_1 100000
0 Sales_1 200000
2 Sales_3 200000
0 Sales_2 300000
2 Sales_1 400000
1 Sales_2 500000
Sales_3 500000
2 Sales_2 1000000
Commissions Sales
0 0.05 0
1 0.04 50000
2 0.03 250000
3 0.02 750000
现在我们可以使用
原始时间测试
非常好地使用了pd.cut
!+1:-)谢谢。PS:我真的想重新安排b
,这样我就可以通过b.销售和b.佣金[1:]
为了更好的清晰度,b
应该如何安排@Boud?我很高兴能让它变得更好/更容易/更清晰。@Kyle在你的callI中交换unstack和astype我相信这可能与此有关。所以在重塑之前请继续使用float。是的,numpy真的很快;)
a_ = a.stack().sort_values().to_frame('Sales')
b_ = pd.DataFrame(dict(
Sales=np.append(0, b.index[:-1]),
Commissions=b.Commission.values
))
print(a_)
print()
print(b_)
Sales
0 Sales_3 100000
1 Sales_1 100000
0 Sales_1 200000
2 Sales_3 200000
0 Sales_2 300000
2 Sales_1 400000
1 Sales_2 500000
Sales_3 500000
2 Sales_2 1000000
Commissions Sales
0 0.05 0
1 0.04 50000
2 0.03 250000
3 0.02 750000
pd.merge_asof(a_, b_).set_index(a_.index).Commissions.unstack()
Sales_1 Sales_2 Sales_3
0 0.04 0.03 0.04
1 0.04 0.03 0.03
2 0.03 0.02 0.04