熊猫将值与其他DataFrame中的相应范围进行匹配

时间:2018-10-16 10:07:41

标签: python pandas dataframe

我有两个数据框。 第一个包含用户ID及其分数(分数列)。另一个数据框包含一些阈值和范围名称。

我需要在第一个df中创建一个新列,如果points列中的值介于“下”和“上”阈值之间,则该列将是第二个df的范围。

enter image description here enter image description here

我尝试使用以下代码:

def r(points):
r = thresholds #thresholds is the df from my second screenshot
if r['lower'] <= points < r['upper']:
    r['range']
return r['range']

PointsEarned['range'] = PointsEarned.points.map(r)

但是我收到此错误ValueError:系列的真值不明确。使用a.empty,a.bool(),a.item(),a.any()或a.all()。

我想我需要在这里使用一些循环来迭代阈值数据帧。

在创建新的“范围”列方面的任何帮助将不胜感激

2 个答案:

答案 0 :(得分:1)

使用pandas.cut,并从upper列中创建垃圾箱,并插入lower列的第一个值:

df = pd.DataFrame(data={'upper': [25,50,75,100,150,250],
                        'lower': [1,25, 50,75,100,150]})

PointsEarned = pd.DataFrame(data={'points': [32,6,80,113]})

bins = np.insert(df['upper'].values, 0, df['lower'].iat[0])
print (bins)
[  1  25  50  75 100 150 250]

PointsEarned['range'] = pd.cut(PointsEarned.points, bins=bins, right=False)

print (PointsEarned)
   points       range
0      32    [25, 50)
1       6     [1, 25)
2      80   [75, 100)
3     113  [100, 150)

答案 1 :(得分:1)

另一种解决方案。这可能会帮助其他人。实际上,您可以在sqlite中构建表并使用联接来匹配范围。

import sqlite3
import sqlalchemy.pool

sqlite = sqlalchemy.pool.manage(sqlite3, poolclass=sqlalchemy.pool.SingletonThreadPool)
conn = sqlite3.connect(":memory:") 
A = pd.DataFrame(data={'points': [32,6,80,113,57,48,5,28,10,11,29,125]})
B = pd.DataFrame(data={'lower': [1,25, 50,75,100,150],
                       'upper': [25,50,75,100,150,250],                        
                       'range': ['[1,25]','[25,50]', '[50,75]','[75,100]','[100,150]','[150,250]']})

A.to_sql("A", conn, index=False)
B.to_sql("B", conn, index=False)
qry = "SELECT points,  lower, upper, range   FROM A left join B on A.points between B.lower and B.upper"
tt = pd.read_sql_query(qry,conn)
print tt