在python中,一个函数将根据另一行上的条件应用于一行中元素的组合
似乎也有类似的问题,但我找不到合适的答案。假设这是我的数据框,它对不同品牌的汽车有不同的观察结果:在python中,一个函数将根据另一行上的条件应用于一行中元素的组合,python,function,pandas,combinations,Python,Function,Pandas,Combinations,似乎也有类似的问题,但我找不到合适的答案。假设这是我的数据框,它对不同品牌的汽车有不同的观察结果: df = pandas.DataFrame({'Car' : ['BMW_1', 'BMW_2', 'BMW_3', 'WW_1','WW_2','Fiat_1', 'Fiat_2'], 'distance' : [10,25,22,24,37,33,49]}) 为简单起见,假设有一个函数,第一个元素乘以2,第二个元素乘以3: def my_fu
df = pandas.DataFrame({'Car' : ['BMW_1', 'BMW_2', 'BMW_3', 'WW_1','WW_2','Fiat_1', 'Fiat_2'],
'distance' : [10,25,22,24,37,33,49]})
为简单起见,假设有一个函数,第一个元素乘以2,第二个元素乘以3:
def my_func(x,y):
z = 2x + 3y
return z
我想得到汽车行驶距离的成对组合,并在我的函数中使用它们。但有两个条件,x和y不能是同一品牌,组合也不能重复。所需的输出如下:
Car Distance Combinations
0 BMW_1 10 (BMW_1,WW_1),(BMW_1,WW_2),(BMW_1,Fiat_1),(BMW_1,Fiat_1)
1 BMW_2 25 (BMW_2,WW_1),(BMW_2,WW_2),(BMW_2,Fiat_1),(BMW_2,Fiat_1)
2 BMW_3 22 (BMW_3,WW_1),(BMW_3,WW_2),(BMW_3,Fiat_1),(BMW_3,Fiat_1)
3 WW_1 24 (WW_1, Fiat_1),(WW_1, Fiat_2)
4 WW_2 37 (WW_2, Fiat_1),(WW_2, Fiat_2)
5 Fiat_1 33 None
6 Fiat_2 49 None
//Output
[120, 134, 156, 178]
[113, 145, 134, 132]
[114, 123, 145, 182]
[153, 123]
[120, 134]
None
None
注:我为输出填写了数字
下一步,我想从每个品牌的“输出”行数组中获取最大数量。最终的数据应该是
Car Max_Distance
0 BMW 178
1 WW 153
2 Fiat None
如果有人能帮助我,我将不胜感激
i, j = np.tril_indices(len(df), 1)
def my_func(x,y):
z = 2 * x + 3 * y
return z
d = df.distance.values
c = df.Car.values
s = pd.Series(my_func(d[i], d[j]), [c[i], c[j]])
def test_name(df):
name = df.index[0]
n1, n2 = map(lambda x: x.split('_')[0], name)
return n1 != n2
s.groupby(level=[0, 1]).filter(test_name).groupby(level=1).apply(list)
BMW_1 [78, 104, 96, 128]
BMW_2 [123, 149, 141, 173]
BMW_3 [114, 140, 132, 164]
Fiat_1 [173]
WW_1 [116, 138, 170]
WW_2 [177, 209]
dtype: object
In [49]: x = pd.DataFrame(np.triu(squareform(pdist(df[['distance']], my_func))),
...: columns=df.Car.str.split('_').str[0],
...: index=df.Car.str.split('_').str[0]).replace(0, np.nan)
...:
In [50]: x[x.apply(lambda col: col.index != col.name)].max(1).max(level=0)
Out[50]:
Car
BMW 197.0
Fiat NaN
WW 221.0
dtype: float64
旧答案:
In [49]: x = pd.DataFrame(np.triu(squareform(pdist(df[['distance']], my_func))),
...: columns=df.Car.str.split('_').str[0],
...: index=df.Car.str.split('_').str[0]).replace(0, np.nan)
...:
In [50]: x[x.apply(lambda col: col.index != col.name)].max(1).max(level=0)
Out[50]:
Car
BMW 197.0
Fiat NaN
WW 221.0
dtype: float64
IIUC您可以执行以下操作:
from scipy.spatial.distance import pdist, squareform
def my_func(x,y):
return 2*x + 3*y
x = pd.DataFrame(
squareform(pdist(df[['distance']], my_func)),
columns=df.Car.str.split('_').str[0],
index=df.Car.str.split('_').str[0])
它产生了:
In [269]: x
Out[269]:
Car BMW BMW BMW WW WW Fiat Fiat
Car
BMW 0.0 95.0 86.0 92.0 131.0 119.0 167.0
BMW 95.0 0.0 116.0 122.0 161.0 149.0 197.0
BMW 86.0 116.0 0.0 116.0 155.0 143.0 191.0
WW 92.0 122.0 116.0 0.0 159.0 147.0 195.0
WW 131.0 161.0 155.0 159.0 0.0 173.0 221.0
Fiat 119.0 149.0 143.0 147.0 173.0 0.0 213.0
Fiat 167.0 197.0 191.0 195.0 221.0 213.0 0.0
排除同一品牌:
In [270]: x.apply(lambda col: col.index != col.name)
Out[270]:
Car BMW BMW BMW WW WW Fiat Fiat
Car
BMW False False False True True True True
BMW False False False True True True True
BMW False False False True True True True
WW True True True False False True True
WW True True True False False True True
Fiat True True True True True False False
Fiat True True True True True False False
In [273]: x[x.apply(lambda col: col.index != col.name)]
Out[273]:
Car BMW BMW BMW WW WW Fiat Fiat
Car
BMW NaN NaN NaN 92.0 131.0 119.0 167.0
BMW NaN NaN NaN 122.0 161.0 149.0 197.0
BMW NaN NaN NaN 116.0 155.0 143.0 191.0
WW 92.0 122.0 116.0 NaN NaN 147.0 195.0
WW 131.0 161.0 155.0 NaN NaN 173.0 221.0
Fiat 119.0 149.0 143.0 147.0 173.0 NaN NaN
Fiat 167.0 197.0 191.0 195.0 221.0 NaN NaN
选择每行的最大值:
In [271]: x[x.apply(lambda col: col.index != col.name)].max(1)
Out[271]:
Car
BMW 167.0
BMW 197.0
BMW 191.0
WW 195.0
WW 221.0
Fiat 173.0
Fiat 221.0
dtype: float64
每个品牌的最大值:
In [276]: x[x.apply(lambda col: col.index != col.name)].max(1).max(level=0)
Out[276]:
Car
BMW 197.0
Fiat 221.0
WW 221.0
dtype: float64
我只是想说清楚。。。你不想将任何宝马与任何其他宝马进行比较吗?是的,没错,只是与不同的品牌进行比较?给定z=2x+3y:bmw_菲亚特2*25+3*49与菲亚特+bmw 2*49+3*25不同。不,在实际功能中这并不重要,它可能类似于x+y。我只想按第一个元素分组哦,也许我不够清楚,对不起,我也不想让WW和菲亚特与它们自己的类型相匹配:(非常感谢你的回答。如果我必须将其应用于一个大型csv文件,它会很有效?@edyvedy13,在你尝试之前你永远不会知道;-)我就快到了,但唯一的一点是,它应该是元素的组合,当我得到宝马的结果时,我不想再将WW与宝马进行比较。然后,我想将WW与菲亚特进行比较,菲亚特基本上什么都没有。我甚至愿意为它付费,如果有人能解决我的问题,因为我正在为它工作4天:/,对不起,我刚刚看到它,如果我们考虑组合和groupby函数,当我们说groupby第一个元素时,应该没有什么留给Fiat了。它有点复杂:/