应用一个函数,该函数具有来自两个不同数据帧的参数,并带有分组依据。 (pandas)
Apply a function that has arguments from two different dataframes, with group by. (pandas)
我有以下任务困扰着我。
我有一个函数,我想按组应用于 pandas 数据框。此函数将另一个数据帧的 1 个系列和当前数据帧的 1 作为输入。我尝试了很多不同的方法,但最终找到了解决方案,但是我想知道是否有更好的方法。
下面我提供了一个可重现的例子。
#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
我认为您可以使用 reset_index()
和参数 drop=True
来删除原始索引值,但通常每个组的必要长度与另一个 DataFrame 的长度相同 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
:
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
对于新列使用 map
:
data1['new'] = data1['target'].map(s)
print (data1.head())
target sepal length (cm) sepal width (cm) petal length (cm) \
0 0.0 5.1 3.5 1.4
1 0.0 4.9 3.0 1.4
2 0.0 4.7 3.2 1.3
3 0.0 4.6 3.1 1.5
4 0.0 5.0 3.6 1.4
petal width (cm) new
0 0.2 238.1
1 0.2 238.1
2 0.2 238.1
3 0.2 238.1
4 0.2 238.1
print (data1.tail())
target sepal length (cm) sepal width (cm) petal length (cm) \
145 2.0 6.7 3.0 5.2
146 2.0 6.3 2.5 5.0
147 2.0 6.5 3.0 5.2
148 2.0 6.2 3.4 5.4
149 2.0 5.9 3.0 5.1
petal width (cm) new
145 2.3 149.0
146 1.9 149.0
147 2.0 149.0
148 2.3 149.0
149 1.8 149.0
我有以下任务困扰着我。 我有一个函数,我想按组应用于 pandas 数据框。此函数将另一个数据帧的 1 个系列和当前数据帧的 1 作为输入。我尝试了很多不同的方法,但最终找到了解决方案,但是我想知道是否有更好的方法。
下面我提供了一个可重现的例子。
#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
我认为您可以使用 reset_index()
和参数 drop=True
来删除原始索引值,但通常每个组的必要长度与另一个 DataFrame 的长度相同 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
:
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
对于新列使用 map
:
data1['new'] = data1['target'].map(s)
print (data1.head())
target sepal length (cm) sepal width (cm) petal length (cm) \
0 0.0 5.1 3.5 1.4
1 0.0 4.9 3.0 1.4
2 0.0 4.7 3.2 1.3
3 0.0 4.6 3.1 1.5
4 0.0 5.0 3.6 1.4
petal width (cm) new
0 0.2 238.1
1 0.2 238.1
2 0.2 238.1
3 0.2 238.1
4 0.2 238.1
print (data1.tail())
target sepal length (cm) sepal width (cm) petal length (cm) \
145 2.0 6.7 3.0 5.2
146 2.0 6.3 2.5 5.0
147 2.0 6.5 3.0 5.2
148 2.0 6.2 3.4 5.4
149 2.0 5.9 3.0 5.1
petal width (cm) new
145 2.3 149.0
146 1.9 149.0
147 2.0 149.0
148 2.3 149.0
149 1.8 149.0