Pandas 基于外部条件向数据帧添加列
给定三个数据帧,一个包含用户数据,第二个包含数据装箱,第三个是类别名称,如中所示:Pandas 基于外部条件向数据帧添加列,pandas,dataframe,merge,Pandas,Dataframe,Merge,给定三个数据帧,一个包含用户数据,第二个包含数据装箱,第三个是类别名称,如中所示: klasses_df = pd.DataFrame([[1, 'Sad'], [7, 'Regular'], [13, 'Happy'], [42, 'Magical']], columns=['kl
klasses_df = pd.DataFrame([[1, 'Sad'],
[7, 'Regular'],
[13, 'Happy'],
[42, 'Magical']],
columns=['klass', 'mood'])
bins_df = pd.DataFrame([[0.0, 3.0, 1],
[3.0, 6.0, 7],
[6.0, 8.0, 13]],
columns=['lower', 'upper', 'klass'])
person_df = pd.DataFrame([['John', 1.5],
['Mary', 3.6],
['Paul', 7.2],
['Josh', 5.7],
['Phil', 9.9]],
columns=['name', 'feeling'])
我想扩展person\u df
(或者创建一个新的数据框),在这里可以找到正确的klass\u id
和情绪。例如,在person\u df
的第一行中,John的感觉位于1.5
,在bins\u df
中,我们可以看到它位于范围第一范围[0,3]
,因此位于klass
1
。查看klass\u df
我们发现klass\u id
1
是Sad
。这将使最后一行/新行与John相关,如John,1.5,1,“Sad”
为此,我创建了两个辅助函数:
def find_klass_from_feeling(feeling, bin_data):
values = bin_data.values
klass = values[(values[:,0] <= feeling) & (feeling < values[:,1])][:,2]
if len(klass) == 0:
return 0
else:
return int(klass.flatten()[0])
def find_mood_from_class(klass, klasses_data):
if klass == 0:
return None
retval = klasses_df[klasses_df['klass'] == klass]['mood'].iloc[0]
return retval
这是可行的,但似乎完全错了,因为我相信,熊猫有一些更合适的方法来处理它。我尝试使用apply
和applymap
,但没有成功
欢迎提供任何提示。首先,这个问题有几个问题:
- 范围包括右值还是左值?现在,我假设没有,值3将进入bin 1
- 超过8的值会发生什么变化?现在,我为超过8的所有值创建新类别“99”
要解决您的问题,可以使用pandas pd.cut()
您需要将您的垃圾箱和标签列在列表中:
您可以手动声明它:
bins = [0.0, 3.0, 6.0, 8.0, float("inf")]
labels = [1, 7, 13, 99]
或者,如果您的数据来自外部,您可以将其转换为:
bins = [0.0]+bins_df['upper'].to_list()+[float("inf")]
label = bins_df['klass'].to_list() + [99]
(我使用99作为伪值,以表示超过8的值缺少类)
现在使用pd.cut()
person_df['klass']=pd.cut(person_df['feeling'], bins = bins, labels=labels)
然后将其链接到心情以获取值:
result = pd.merge(person_df, klasses_df, on='klass', how='left')
print(result)
输出:
name feeling klass mood
0 John 1.5 1 Sad
1 Mary 3.6 7 Regular
2 Paul 7.2 13 Happy
3 Josh 5.7 7 Regular
4 Phil 9.9 99 NaN
(Phil不在指定范围内,因此没有心情)查看“非相等联接”,如此处所述:您可以将装箱重写为不同的格式,还是必须是此数据帧(即,如果箱子可以在列表中,这更易于管理)?另外,菲尔的分数超出了bin的范围,你的bin在开始和结束时都有相同的值。例如,如果一个人降落在3号货位上,他们应该属于1号货位还是7号货位?lower
name feeling klass mood
0 John 1.5 1 Sad
1 Mary 3.6 7 Regular
2 Paul 7.2 13 Happy
3 Josh 5.7 7 Regular
4 Phil 9.9 99 NaN