我在熊猫df1中有一张桌子
id value
1 1500
2 -1000
3 0
4 50000
5 50
我在数据帧df2中还有另一个表,该表包含组的上限,因此基本上每一行都代表从前一个边界到当前边界的间隔(第一个间隔是“ <0”):
group upper
0 0
1 1000
2 NaN
我应该如何使用df2中的间隔从df中获得价值的相关组?我不能使用连接,合并等,因为此连接的规则应类似于“如果值在先前的上限和当前上限之间”,而不是“如果值等于某值”。我发现的唯一方法是将预定义函数与df.apply()一起使用(在其中也存在带有interval_flag == False的分类值的情况):
def values_to_group(x, interval_flag, groups_def):
if interval_flag==True:
for ind, gr in groups_def.sort_values(by='group').iterrows():
if x<gr[1]:
return gr[0]
elif math.isnan(gr[1]) == True:
return gr[0]
else:
for ind, gr in groups_def.sort_values(by='group').iterrows():
if x in gr[1]:
return gr[0]
有没有更简单/更优化的方法?
预期输出应为:
id value group
1 1500 2
2 -1000 0
3 0 1
4 50000 2
5 50 1
答案 0 :(得分:0)
我建议将DataFrame
中的df2
中的upper
与NaN
一起使用,并将最后的np.inf
替换为df2 = pd.DataFrame({'group':[0,1,2], 'upper':[0,1000,np.nan]})
df2 = df2.sort_values('upper')
df2['upper'] = df2['upper'].replace(np.nan, np.inf)
print (df2)
group upper
0 0 0.000000
1 1 1000.000000
2 2 inf
#added first bin -np.inf
bins = np.insert(df2['upper'].values, 0, -np.inf)
df1['group'] = pd.cut(df1['value'], bins=bins, labels=df2['group'], right=False)
print (df1)
id value group
0 1 1500 2
1 2 -1000 0
2 3 0 1
3 4 50000 2
4 5 50 1
:
#pricing
答案 1 :(得分:0)
这是使用numpy.digitize
的解决方案。您唯一的任务是构造bins
和names
输入列表,这应该可以通过输入数据框实现。
import pandas as pd, numpy as np
df = pd.DataFrame({'val': [99, 53, 71, 84, 84]})
df['ratio'] = df['val']/ df['val'].shift() - 1
bins = [-np.inf, 0, 0.2, 0.4, 0.6, 0.8, 1.0, np.inf]
names = ['<0', '0.0-0.2', '0.2-0.4', '0.4-0.6', '0.6-0.8', '0.8-1.0', '>1']
d = dict(enumerate(names, 1))
df['Bucket'] = list(map(d.get, np.digitize(df['ratio'], bins)))
print(df)
val ratio Bucket
0 99 NaN None
1 53 -0.464646 <0
2 71 0.339623 0.2-0.4
3 84 0.183099 0.0-0.2
4 84 0.000000 0.0-0.2