2017-08-29 53 views
2

如果不采用循环方式处理数据帧的每一行(对于大型数据集可能非常缓慢),如何使用连续两列的计算结果2*A - B来查找列B中的值以及来自该新行的值从列C的行拉数据并放置在原始行的列D中。基于列数据计算,在Pandas DataFrame中从另一行查找数据的最快方法?

在下面的DataFrame中,例如,行2具有2*A - B等于1。行0中的列B具有1,因此来自行0的列C的数据应该放在行2的列D中。

In [1] import pandas as pd 
In [2] a = [3,3,3] 
In [3] b = [1,3,5] 
In [4] c = [3,4,5] 

In [5] df1 = pd.DataFrame({'A': a , 'B': b, 'C':c}) 
Out[5] print(df1) 

    A B C 
0 3 1 3 
1 3 3 4 
2 3 5 5 

产生的数据帧应该是这样的:

A B C D 
0 3 1 3 5 
1 3 3 4 4 
2 3 5 5 3 

我假设只有一个为AB每种组合的独特价值。虽然上面的例子可以通过将列C转换成列D来实现,但我想要一个更通用的解决方案,可扩展到数据不适合转置的情况。

回答

2

使用pd.DataFrame.eval

df1.assign(D=df1.eval('2 * A - B').map(df1.set_index('B').C)) 

    A B C D 
0 3 1 3 5 
1 3 3 4 4 
2 3 5 5 3 

但是,如果快是你想要的。

m = dict(zip(df1.B.values.tolist(), df1.C.values.tolist())) 
a = df1.A.values 
b = df1.B.values 
z = 2 * a - b 

df1.assign(D=[m[i] for i in z.tolist()]) 

    A B C D 
0 3 1 3 5 
1 3 3 4 4 
2 3 5 5 3 
+0

你说得对,第二种方法比第一种方法快2-3倍,这本身明显快于其他解决方案。由于这个原因,我将你的答案标记为解决方案。尽管其他解决方案对其方法有更好的解释。 – DakotaD

3

如果你能保证独特组合,然后...

mapping = dict(df[['B', 'C']].values) 
df['D'] = (2 * df.A - df.B).replace(mapping) 
df  
    A B C D 
0 3 1 3 5 
1 3 3 4 4 
2 3 5 5 3 

创建B值映射到C值。执行操作(2 * A - B),并使用之前生成的mapping来获得适当的C值。

如果映射不存在,则计算的值不会被替换。如果你想它与NaN被替换,您可以使用map代替:

df['D'] = (2 * df.A - df.B).map(mapping) 
df 
    A B C D 
0 3 1 3 5 
1 3 3 4 4 
2 3 5 5 3 

它的工作原理df.replace会,但非映射值与NaN取代。

相关问题