Python 使用矢量化将列查找值相乘的更快方法
我有两个数据帧,一个包含值,是工作数据集(postsolutionDF),而另一个只是作为查找表(FactoryPortPCNTDF)参考。目标是向postsolutionDF添加一列,该列包含postsolutionDF每行的查找值的乘积(新列名=num_predict)。然后将该乘积乘以2700。例如,在第一行上,工作值为0.5,2,-6。这些的等效查找值为0.1182、0.2098和0.8455。它们的乘积是0.0209,当乘以2700时,结果是56.61,如输出所示 下面的代码适用于这个简化的示例,但在实际解决方案中速度非常慢(1.6MM行x 15个编号列)。我确信有一个更好的方法可以通过删除“fork in range”循环来实现这一点,但我正在努力解决这个问题,因为已经在行上使用了apply。我已经找到了许多无关紧要的解决办法,但对我的情况还没有起到任何作用。谢谢你的帮助Python 使用矢量化将列查找值相乘的更快方法,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,我有两个数据帧,一个包含值,是工作数据集(postsolutionDF),而另一个只是作为查找表(FactoryPortPCNTDF)参考。目标是向postsolutionDF添加一列,该列包含postsolutionDF每行的查找值的乘积(新列名=num_predict)。然后将该乘积乘以2700。例如,在第一行上,工作值为0.5,2,-6。这些的等效查找值为0.1182、0.2098和0.8455。它们的乘积是0.0209,当乘以2700时,结果是56.61,如输出所示 下面的代码适用于这个
import pandas as pd
import numpy as np
postsolutionDF = pd.DataFrame({'SCRN' : (['2019-01-22-0000001', '2019-01-22-0000002', '2019-01-22-0000003']), '1' : 0.5,
'2' : 2, '3' : ([-6, 1.0, 8.0])})
postsolutionDF = postsolutionDF[['SCRN', '1', '2', '3']]
print('printing initial postsolutionDF..')
print(postsolutionDF)
factorimportpcntDF = pd.DataFrame({'F1_Val' : [0.5, 1, 1.5, 2], 'F1_Pcnt' : [0.1182, 0.2938, 0.4371, 0.5433], 'F2_Val'
: [2, 3, np.nan, np.nan], 'F2_Pcnt' : [0.2098, 0.7585, np.nan, np.nan], 'F3_Val' : [-6, 1, 8, np.nan], 'F3_Pcnt' :
[0.8455, 0.1753, 0.072, np.nan]})
print('printing factorimportpcntDF..')
print(factorimportpcntDF)
def zero_filter(row): # row is series
inner_value = 1
for k in range(1, 4): # number of columns in postsolutionDF with numeric headers, dynamic in actual code
inner_value *= factorimportpcntDF.loc[factorimportpcntDF['F'+str(k)+'_Val']==row[0+k], 'F'+str(k)+'_Pcnt'].values[0]
inner_value *= 2700
return inner_value
postsolutionDF['num_predict'] = postsolutionDF.apply(zero_filter, axis=1)
print('printing new postsolutionDF..')
print(postsolutionDF)
打印输出:
C:\ProgramData\Anaconda3\python.exe C:/Users/Eric/.PyCharmCE2017.3/config/scratches/scratch_5.py
printing initial postsolutionDF..
SCRN 1 2 3
0 2019-01-22-0000001 0.5 2 -6.0
1 2019-01-22-0000002 0.5 2 1.0
2 2019-01-22-0000003 0.5 2 8.0
printing factorimportpcntDF..
F1_Pcnt F1_Val F2_Pcnt F2_Val F3_Pcnt F3_Val
0 0.1182 0.5 0.2098 2.0 0.8455 -6.0
1 0.2938 1.0 0.7585 3.0 0.1753 1.0
2 0.4371 1.5 NaN NaN 0.0720 8.0
3 0.5433 2.0 NaN NaN NaN NaN
printing new postsolutionDF..
SCRN 1 2 3 num_predict
0 2019-01-22-0000001 0.5 2 -6.0 56.610936
1 2019-01-22-0000002 0.5 2 1.0 11.737312
2 2019-01-22-0000003 0.5 2 8.0 4.820801
Process finished with exit code 0
我不知道如何在本地熊猫身上做到这一点,但如果你回到努比,这是相当容易的 该函数设计用于在查找表中的值之间进行插值,但如果输入值与查找表中的值完全匹配(就像您的一样),则它将变成一个简单的查找,而不是插值
postsolutionDF['1new'] = np.interp(postsolutionDF['1'].values, factorimportpcntDF['F1_Val'], factorimportpcntDF['F1_Pcnt'])
postsolutionDF['2new'] = np.interp(postsolutionDF['2'].values, factorimportpcntDF['F2_Val'], factorimportpcntDF['F2_Pcnt'])
postsolutionDF['3new'] = np.interp(postsolutionDF['3'].values, factorimportpcntDF['F3_Val'], factorimportpcntDF['F3_Pcnt'])
postsolutionDF['num_predict'] = postsolutionDF['1new'] * postsolutionDF['2new'] * postsolutionDF['3new'] * 2700
postsolutionDF.drop(columns=['1new', '2new', '3new'], inplace=True)
给出输出:
In [167]: postsolutionDF
Out[167]:
SCRN 1 2 3 num_predict
0 2019-01-22-0000001 0.5 2 -6.0 56.610936
1 2019-01-22-0000002 0.5 2 1.0 11.737312
2 2019-01-22-0000003 0.5 2 8.0 4.820801
我必须填充factorymportpcntdf,以便所有列都有4个值,否则查找列的最高值将不起作用。您可以多次使用相同的值,或者将其拆分为3个查找表(如果愿意),然后列的长度可以不同
factorimportpcntDF = pd.DataFrame({'F1_Val' : [0.5, 1, 1.5, 2], 'F1_Pcnt' : [0.1182, 0.2938, 0.4371, 0.5433],
'F2_Val' : [2, 3, 3, 3], 'F2_Pcnt' : [0.2098, 0.7585, 0.7585, 0.7585],
'F3_Val' : [-6, 1, 8, 8], 'F3_Pcnt' : [0.8455, 0.1753, 0.072, 0.072]})
请注意,文档指定您的
F1_val
etc列需要按递增顺序排列(您的列在这里,仅供参考)。否则,interp将运行,但不一定会给出好的结果。您能解释第2行吗?我理解第1行阅读您的问题,但不理解如何处理第2行。两个DFs中的索引是否相互对应?也就是说,factorymportpcntdf
中的索引0是在postsolutionDF
中查找索引0吗?如果是,或者如果您有任何其他方法将数据帧合并为一个,您可以轻松地将计算矢量化。我可以看到您的DFs具有不同的长度,这表明索引不对应。另外,postsolutionDF
中的[“1”、“2”、“3”]
列似乎与第一行的[“F1\u Val”、“F2\u Val”、“F3\u Val”]
列相匹配,但与其他行不匹配,这表明我们也无法在这些行上合并。索引不对应。postsolutionDF索引上升到约1.6MM,而factorimportpcntDF索引在所示的4行中是静态的。postsolutionDF中的列与factorimportpcntDF中的列相对应。例如,postsolutionDF中的列“1”将始终对应于FactoryPortPCNTDF中的查找列“F1_-Val”,以及FactoryPortPCNTDF中的结果值列“F1_-Pcnt”。实际上,您可以根据factorymportpcntdf中的“F1_Val”和“F1_Pcnt”列,为postsolutionDF中的每个编号列创建一个查找dict。非常重要的澄清!