基于列数据计算,在Pandas DataFrame中从另一行查找数据的最快方法?
问题描述:
如果不采用循环方式处理数据帧的每一行(对于大型数据集可能非常缓慢),如何使用连续两列的计算结果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
我假设只有一个为A
和B
每种组合的独特价值。虽然上面的例子可以通过将列C
转换成列D
来实现,但我想要一个更通用的解决方案,可扩展到数据不适合转置的情况。
答
使用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
答
如果你能保证独特组合,然后...
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
取代。
你说得对,第二种方法比第一种方法快2-3倍,这本身明显快于其他解决方案。由于这个原因,我将你的答案标记为解决方案。尽管其他解决方案对其方法有更好的解释。 – DakotaD