我有一个像这样的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列。我正在寻找一种快速有效的计算方法。感谢
答案 0 :(得分:3)
# 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