用列数组向量化pandas dataframe列查找

时间:2019-05-15 06:47:04

标签: python pandas numpy vectorization

我有一个字符串的熊猫数据框,如下所示。

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(97,123,size=(3, 4), dtype=np.uint8).view('S1'), columns=list('ABCD'))
df

出局:

   A  B  C  D
0  q  g  v  f
1  l  m  u  u
2  r  r  j  w

我还有一个列名列表。

col_list = [['A'], ['A', 'B'], ['A', 'B', 'C']]

我想对df进行切片并执行如下操作:

df[col_list[1]].values.sum(axis=1)

出局:

array(['qg', 'lm', 'rr'], dtype=object)

类似地,我需要对col_list中的所有项目执行此操作。我可以在for循环中执行此操作,但是对于大型列表而言,这样做会很慢。有什么方法可以向量化它,以便我可以将col_list作为一个numpy数组传递,结果是一个形状为(len(col_list), len(df.index))的numpy 2D数组。

要点是,对于大型列表,它需要快速。

1 个答案:

答案 0 :(得分:2)

numpyr_cumsumhsplit结合使用:

import numpy as np

arr_list = np.hsplit(df.loc[:, np.r_[[i for l in col_list for i in l]]].values, 
               np.cumsum(list(map(len, col_list))))
res1 = list(map(lambda x:np.sum(x, 1), arr_list))[:-1]
如果col_list有3000个列表,

比普通循环快60倍:

col_list = [['A'], ['A', 'B'], ['A', 'B', 'C']] * 1000

numpy

%%timeit

arr_list = np.hsplit(df.loc[:, np.r_[[i for l in col_list for i in l]]].values, 
               np.cumsum(list(map(len, col_list))))
res1 = list(map(lambda x:np.sum(x, 1), arr_list))[:-1]
# 24.3 ms ± 3.36 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

for循环:

%%timeit

for l in col_list:
    df[l].values.sum(axis=1)
# 1.53 s ± 62.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

验证:

all(all(i == j) for i,j in zip(res1, res2))
# True