熊猫 / numpy在柱标头和索引标头之间找到差异的方法



我有一个看起来像这样的pandas dataframe:

import pandas as pd
cols = [1,2,5,15]
rows = [1,0,4]
data = pd.DataFrame(np.zeros((len(rows),len(cols))))
data.columns = cols
data.index = rows
    1   2   5   15
1   0.0 0.0 0.0 0.0
0   0.0 0.0 0.0 0.0
4   0.0 0.0 0.0 0.0

我想找到列的标题和索引/行标头之间的区别,使得绝对差异填充了表:

    1   2   5   15
1   0.0 1.0 4.0 14.0
0   1.0 2.0 5.0 15.0
4   3.0 2.0 1.0 11.0

他们是熊猫还是努力的方式?在这里,我正在使用一个小的数据集,实际上,我有将近1000,000行和100列。我正在寻找一种快速有效的计算方法。谢谢

使用NumPy broadcasting-

一种方法
# Extract index and column as int arrays
indx = df.index.values.astype(int)
cols = df.columns.values.astype(int)
# Perform elementwise subtracttion between all elems of indx against all cols
a = np.abs(indx[:,None] - cols)
df_out = pd.DataFrame(a, df.index, df.columns)

样本输入,输出 -

In [43]: df
Out[43]: 
     1    2    5   15
1  0.0  0.0  0.0  0.0
0  0.0  0.0  0.0  0.0
4  0.0  0.0  0.0  0.0
In [44]: df_out
Out[44]: 
   1  2  5  15
1  0  1  4  14
0  1  2  5  15
4  3  2  1  11

另外,对于df中的原位编辑,请用df[:]分配 -

In [58]: df[:] = a
In [59]: df
Out[59]: 
   1  2  5  15
1  0  1  4  14
0  1  2  5  15
4  3  2  1  11

另外,如果我们确实可以访问索引和列信息,我们可以直接从它们中获取a,例如So-

a = np.abs(np.asarray(rows)[:,None] - cols)

进一步的性能提升

我们可以使用numexpr模块进一步提高它,以执行大型数据集的absolute计算,以获取a,例如So -

import numexpr as ne
def elementwise_abs_diff(rows, cols): # rows would be indx
    I = np.asarray(rows)[:,None]
    return ne.evaluate('abs(I - cols)')

这给了我们a,可以喂食以创建前面显示的df_out或分配回df

时间 -

In [93]: rows = np.random.randint(0,9,(5000)).tolist()
In [94]: cols = np.random.randint(0,9,(5000)).tolist()
In [95]: %timeit np.abs(np.asarray(rows)[:,None] - cols)
10 loops, best of 3: 65.3 ms per loop
In [96]: %timeit elementwise_abs_diff(rows, cols)
10 loops, best of 3: 32 ms per loop

最新更新