编写此lambda函数的更有效方法

2024-09-30 22:28:31 发布

您现在位置:Python中文网/ 问答频道 /正文

import pandas as pd

prizes = ([1, 100], [2, 50], [3, 25])
prizes = pd.DataFrame(prizes, columns=['Rank', 'Payout'])

ranking = ([1, 3, 2], [2, 2, 1], [3, 1, 3])
ranking = pd.DataFrame(ranking, columns=[1, 2, 3])

payouts = pd.DataFrame(range(1, 4), columns=['Lineup'])
mapper = prizes.set_index('Rank')['Payout'].to_dict()
payouts = pd.concat([payouts, ranking[range(1, 4)].apply(lambda s: s.map(mapper)).fillna(-1)], axis=1)

print(ranking)
print(payouts)

   1  2  3
0  1  3  2
1  2  2  1
2  3  1  3
   Lineup    1    2    3
0       1  100   25   50
1       2   50   50  100
2       3   25  100   25

就在print语句上方的lambda函数,有什么方法可以更有效地编写它。这只是我在一个大循环中使用它的一个小例子。循环的这一部分大约占整个循环时间的一半。任何帮助都将不胜感激


Tags: columnslambdaimportdataframepandasrangepdprint
2条回答

下面是一个使用底层numpy数组的更快(但不那么简洁)的解决方案。与replace相比,有约1.7倍的增益

a = prizes.set_index('Rank')['Payout'].values
b = ranking.values-1 # get index as 0/1/2
c = a.take(b.flatten()).reshape(b.shape) # index in 1D and reshape to 2D
pd.DataFrame(c, columns=ranking.columns)

NB。为了清晰起见,我将步骤分解了,但这可以在没有中间变量的情况下完成

输出:

     1    2    3
0  100   25   50
1   50   50  100
2   25  100   25

您不需要为mapper创建dict,设置索引并确保它是一个系列就足够了(从某种意义上说,系列就是dict);关于你的问题,你可以用replace;它应该更快:

mapper = prizes.set_index('Rank')['Payout']

pd.concat([payouts, ranking.replace(mapper)], axis=1)

   Lineup    1    2    3
0       1  100   25   50
1       2   50   50  100
2       3   25  100   25

你的例子没有显示需要一个fillna;对于这种情况,您可以向数据中添加额外的详细信息。此外,由于支出只是一列,您可以创建一个系列,从中可以获得一些性能增益

相关问题 更多 >