我有以下任务困扰我。 我有一个函数,我想按组应用于pandas数据帧。此函数将来自另一个数据帧的1个系列作为输入,将来自当前数据的1作为输入。我尝试了很多不同的方法,但最终我找到了一个解决方案,但我想知道是否有更好的方法。
Bellow我提供了一个可重复的例子。
#load the data
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
data1 = pd.DataFrame(data= np.c_[ iris['target'], iris['data']], columns= ['target'] + iris['feature_names'] )
data2 = pd.DataFrame({'x' : data1[data1.target == 0].iloc[:,1], 'y' :data1[data1.target == 0].iloc[:,2]})
# define one random function
def some_function(x, p):
err = (x - p )
return sum(err)
所以我的第一次尝试是:
data1.groupby('target').apply(lambda x: some_function(data2.iloc[:,0], data1.iloc[:,4])) # this does not work
尝试了许多不同的方法后,
data1.groupby('target').apply(lambda x: some_function(data1.iloc[:,1], data1.iloc[:,4])) # this works
data1.groupby('target').apply(lambda x: some_function(data2.iloc[:,1],data1[data1.target==0].iloc[:,4])) # this works
data1.groupby('target').apply(lambda x: some_function(data2.iloc[:,1], data1[data1.target==1].iloc[:,4])) # this does not work
我发现(经过很长一段时间)索引存在问题。以下是有效的。
data1.groupby('target').apply(lambda x: some_function(data2.iloc[:,0], x.iloc[:,4].reset_index().iloc[:,1]))
还有其他方法吗?为什么我最后使用axis = 1
它不起作用?
最后,如何在data1的新行中添加它?类似的东西,它不会将结果合并到所有行。
data1.groupby('target')['new_column'] = data1.groupby('target').apply(lambda x: some_function(data2.iloc[:,0], x.iloc[:,4].reset_index().iloc[:,1]))
或不使用groupby
答案 0 :(得分:1)
我认为您可以使用带有参数reset_index()
的{{1}}来删除原始索引值,但通常每个组的必要长度与另一个DataFrame drop=True
的长度相同:
测试长度:
data2
s1 = data1.groupby('target').size()
print (s1)
target
0.0 50
1.0 50
2.0 50
dtype: int64
print (len(data2))
50
替代方案是将s = (data1.groupby('target')
.apply(lambda x: some_function(data2.iloc[:,0],
x.iloc[:,4].reset_index(drop=True))))
转换为Series
:
numpy array
对于新列使用map
:
s=data1.groupby('target').apply(lambda x: some_function(data2.iloc[:,0],x.iloc[:,4].values))
print (s)
target
0.0 238.1
1.0 184.0
2.0 149.0
dtype: float64