【发布时间】:2019-12-10 09:09:04
【问题描述】:
我有以下熊猫数据框:
import numpy as np
import pandas as pd
np.random.seed(0)
test_df = pd.DataFrame({"category": ["A", "B"]*5, "value": np.random.uniform(size=10)})
print(test_df)
# category value
#0 A 0.548814
#1 B 0.715189
#2 A 0.602763
#3 B 0.544883
#4 A 0.423655
#5 B 0.645894
#6 A 0.437587
#7 B 0.891773
#8 A 0.963663
#9 B 0.383442
我想使用pandas.cut 对value 列进行分箱,但bins 参数需要根据category 列而有所不同。
具体来说,我想使用以下字典来定义用于cut 的垃圾箱:
bins = {
"A": [0.00, 0.25, 0.50, 0.75, 1],
# 0, 1, 2, 3, 4 <-- corresponding bin value
"B": [0.00, 0.33, 0.66, 1]
# 0, 1, 2, 3 <-- corresponding bin value
}
我想出了以下解决方案,即首先使用所有 bin 剪切 value 列:
cuts = {
c: pd.cut(test_df["value"], bins=bins[c], labels=range(1, len(bins[c]))) for c in bins
}
然后使用numpy.select将适当的bin分配回test_df:
test_df["bin"] = np.select(*zip(*[(test_df["category"] == c, cuts[c]) for c in bins]))
print(test_df)
# category value bin
#0 A 0.548814 3
#1 B 0.715189 3
#2 A 0.602763 3
#3 B 0.544883 2
#4 A 0.423655 2
#5 B 0.645894 2
#6 A 0.437587 2
#7 B 0.891773 3
#8 A 0.963663 4
#9 B 0.383442 2
这是正确的答案,但有没有更有效的方法?理想情况下,应该有一种不涉及在每个不同的垃圾箱上调用cut 的方法。在我的真实数据中,我有超过 2 个 bin。
【问题讨论】: