Pandas / Numpy查找列标题和索引标题之间差异的方法

时间:2017-06-01 02:50:54

标签: python pandas 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

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

1 个答案:

答案 0 :(得分:3)

使用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,如此 -

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

进一步提升绩效

我们可以使用numexpr module进一步提升它,以便为大型数据集执行absolute次计算,以获得a,就像这样 -

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