稀疏矩阵中的快速逐行布尔运算

fast row-wise boolean operations in sparse matrices

我有一个约 440 万的采购订单数据框。我对指示该采购订单中存在某些项目的列感兴趣。它的结构如下:

df['item_arr'].head()
1   [a1, a2, a5]
2   [b1, b2, c3...
3   [b3]
4   [a2] 

有 4k 个不同的项目,并且每一行总是至少有一个。我生成了另一个 4.4M x 4k 数据帧 df_te_sub,其稀疏结构表示布尔值相同的数组,即

c = df_te_sub.columns[[10, 20, 30]]
df_te_sub[c].head()
>>a10   b8  c1
0   0   0   0
1   0   0   0
2   0   0   0
3   0   0   0
4   0   0   0

列的名称并不重要,尽管它是按字母顺序排列的,但重要的是。

给定项目的子集 g,我正在尝试为两种不同的情况提取订单(行):

  1. 行中至少存在一项

  2. 行中存在的项目都是 g

    的子集

我发现最好的第一条规则是:

c = df_te_sub[g].sparse.to_coo()
rows = pd.unique(c.row)

第二条规则提出了挑战。我尝试了不同的方法,但它们都很慢:

# using set
s = set(g)
df['item_arr'].apply(s.issuperset)

# using the "non selected items"
c = df_te_sub[df_te_sub.columns[~df_te_sub.columns.isin(g)]].sparse.to_coo()
x = np.ones(len(df_te_sub), dtype='bool')
x[c.row] = False

# mix
s = set(g)
c = df_te_sub[g].sparse.to_coo()
rows = pd.unique(c.row)
df['item_arr'].iloc[rows].apply(s.issuperset)

有什么提高性能的想法吗?我需要为几个子集执行此操作。

输出可以按行(例如 [0, 2, 3])或布尔掩码(例如 True False True True ....)给出,因为两者都可以对订单数据帧进行切片。

我觉得你想多了。如果您有一个成员资格的布尔数组,那么您已经完成了 90% 的工作。

from scipy.sparse import csc_matrix

# Turn your sparse data into a sparse array
arr = csc_matrix(df_te_sub.sparse.to_coo())

# Get the number of items per row
row_len = arr.sum(axis=1).A.flatten()

# Get the column indices for each item and slice your array
arr_col_idx = [df.columns.get_loc(g_val) for g_val in g]

# Sum the number of items in g in the slice per row
arr_g = arr[:, arr_col_idx].sum(axis=1).A.flatten()

# Find all the rows with at least one thing in g
arr_one_g = arr_g > 0

# Find all the things in the rows which are subsets of G
# This assumes row_len is always greater than 0, if it isnt add a test for that
arr_subset_g = (row_len - arr_g) == 0

arr_one_garr_subset_g 是一维布尔数组,应该为你想要的东西建立索引。