我有一个包含30列和大约250k行的pandas数据框,我想扩展它以包含所有变量的相乘。
目前我正在做以下事情,并且它有效,但速度非常慢。有没有更好的方法来达到同样的效果?
import itertools
for p in itertools.combinations(range(1,30),2): #First column is an id, so not included
newColName = df.columns[p[0]] + '*' + df.columns[p[1]] #Create the name of the column
df[newColName] = df[[p[0]]].values * df[[p[1]]].values
答案 0 :(得分:1)
它与您的代码基本上非常相似,但我有一个显着的加速重写代码,如下所示。
In [185]: from string import ascii_lowercase
In [186]: df_base = pd.DataFrame({l:range(250000) for l in ascii_lowercase})
In [173]: %%time
...: df = df_base.copy()
...: for pair in combinations(df.columns, 2):
...: new_col = '*'.join(pair)
...: df[new_col] = df[pair[0]] * df[pair[1]]
Wall time: 10.5 s
我认为主要区别来自于乘法df[a] * d[b]
,而不是df[[a]] * df[[b]]
这里有一些代码显示速度的示例差异。
In [199]: %timeit df['a'] * df['b']
1000 loops, best of 3: 1.88 ms per loop
In [200]: %timeit df[['a']] * df[['b']]
1 loops, best of 3: 21.3 ms per loop
答案 1 :(得分:0)
您可以使用numpy.repeat
和numpy.tile
,然后将两个元素相乘:
>>> df
A B
0 -41 55
1 -17 -53
2 -33 -130
>>> np.repeat(df.values, 2, axis=1)
array([[ -41., -41., 55., 55.],
[ -17., -17., -53., -53.],
[ -33., -33., -130., -130.]])
>>> np.tile(df.values, 2)
array([[ -41., 55., -41., 55.],
[ -17., -53., -17., -53.],
[ -33., -130., -33., -130.]])
列的名称映射类似:
>>> [x+y for x, y in zip(np.repeat(df.columns, 2), np.tile(df.columns, 2))]
['AA', 'AB', 'BA', 'BB']