计算 dask 数据帧中所有行差异的有效方法
Efficient way to compute difference of all rows in dask dataframe
我正在寻找计算 dask 数据帧中所有行差异的有效方法(首选)或 pandas 中的任何有效方法 df.I 有数百万行的巨大文件,它需要像永远计算这个..下面是例子:
d = {'A': [5, 9, 15, 0, 2], 'B': [7, 6, 3, 1, 4], 'C': [8, 11, 2, 5, 3]}
df = pd.DataFrame(data=d, index=['i1', 'i2', 'i3', 'i4', 'i5'])
print(df)
tmp = pd.DataFrame(columns=['A', 'B', 'C'])
row_pointer = 1
for index, row in df.iterrows():
for i, r in df.iloc[row_pointer:].iterrows():
tmp.loc['(' + index + ' - ' + i + ')'] = df.loc[index] - df.loc[i]
row_pointer += 1
print(tmp)
输出:
A B C
i1 5 7 8
i2 9 6 11
i3 15 3 2
i4 0 1 5
i5 2 4 3
A B C
(i1 - i2) -4 1 -3
(i1 - i3) -10 4 6
(i1 - i4) 5 6 3
(i1 - i5) 3 3 5
(i2 - i3) -6 3 9
(i2 - i4) 9 5 6
(i2 - i5) 7 2 8
(i3 - i4) 15 2 -3
(i3 - i5) 13 -1 -1
(i4 - i5) -2 -3 2
使用广播来做所有的减法。然后在 <
之后进行子集化以获得所有唯一组合。
import pandas as pd
import numpy as np
arr = df.to_numpy()
res = pd.DataFrame(np.vstack(arr[:, None]-arr),
index=pd.MultiIndex.from_product([df.index, df.index]))
res = res[res.index.get_level_values(0) < res.index.get_level_values(1)]
print(res)
0 1 2
i1 i2 -4 1 -3
i3 -10 4 6
i4 5 6 3
i5 3 3 5
i2 i3 -6 3 9
i4 9 5 6
i5 7 2 8
i3 i4 15 2 -3
i5 13 -1 -1
i4 i5 -2 -3 2
数百万行可能不可行。或者删除循环的一级:
from itertools import chain
arr = df.to_numpy()
data = [(arr[i, None]-arr)[i+1:] for i in range(np.shape(arr)[0])]
idx = pd.MultiIndex.from_product([df.index, df.index])
idx = idx[idx.get_level_values(0) < idx.get_level_values(1)]
res = pd.DataFrame(chain.from_iterable(data), index=idx)
我使用 dask 数组获取输出:
arr = df.to_numpy()
x = da.from_array(arr, chunks=(100))
diff = abs(x[:, None] - x)
diff[0:1000].compute()
diff[1000:2000].compute()
diff[2000:3000].compute()
我使用 Dask 惰性计算为大于内存的数组生成结果。
我正在寻找计算 dask 数据帧中所有行差异的有效方法(首选)或 pandas 中的任何有效方法 df.I 有数百万行的巨大文件,它需要像永远计算这个..下面是例子:
d = {'A': [5, 9, 15, 0, 2], 'B': [7, 6, 3, 1, 4], 'C': [8, 11, 2, 5, 3]}
df = pd.DataFrame(data=d, index=['i1', 'i2', 'i3', 'i4', 'i5'])
print(df)
tmp = pd.DataFrame(columns=['A', 'B', 'C'])
row_pointer = 1
for index, row in df.iterrows():
for i, r in df.iloc[row_pointer:].iterrows():
tmp.loc['(' + index + ' - ' + i + ')'] = df.loc[index] - df.loc[i]
row_pointer += 1
print(tmp)
输出:
A B C
i1 5 7 8
i2 9 6 11
i3 15 3 2
i4 0 1 5
i5 2 4 3
A B C
(i1 - i2) -4 1 -3
(i1 - i3) -10 4 6
(i1 - i4) 5 6 3
(i1 - i5) 3 3 5
(i2 - i3) -6 3 9
(i2 - i4) 9 5 6
(i2 - i5) 7 2 8
(i3 - i4) 15 2 -3
(i3 - i5) 13 -1 -1
(i4 - i5) -2 -3 2
使用广播来做所有的减法。然后在 <
之后进行子集化以获得所有唯一组合。
import pandas as pd
import numpy as np
arr = df.to_numpy()
res = pd.DataFrame(np.vstack(arr[:, None]-arr),
index=pd.MultiIndex.from_product([df.index, df.index]))
res = res[res.index.get_level_values(0) < res.index.get_level_values(1)]
print(res)
0 1 2
i1 i2 -4 1 -3
i3 -10 4 6
i4 5 6 3
i5 3 3 5
i2 i3 -6 3 9
i4 9 5 6
i5 7 2 8
i3 i4 15 2 -3
i5 13 -1 -1
i4 i5 -2 -3 2
数百万行可能不可行。或者删除循环的一级:
from itertools import chain
arr = df.to_numpy()
data = [(arr[i, None]-arr)[i+1:] for i in range(np.shape(arr)[0])]
idx = pd.MultiIndex.from_product([df.index, df.index])
idx = idx[idx.get_level_values(0) < idx.get_level_values(1)]
res = pd.DataFrame(chain.from_iterable(data), index=idx)
我使用 dask 数组获取输出:
arr = df.to_numpy()
x = da.from_array(arr, chunks=(100))
diff = abs(x[:, None] - x)
diff[0:1000].compute()
diff[1000:2000].compute()
diff[2000:3000].compute()
我使用 Dask 惰性计算为大于内存的数组生成结果。