我有一个看起来像这样的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