我有一个非常大的数据框
in>> all_data.shape
out>> (228714, 436)
我想要做的有效的是将许多列加在一起。我开始使用for循环和列列表 - 我找到的最有效的方法是
from itertools import combinations
newcolnames=list(all_data.columns.values)
newcolnames=newcolnames[0:87]
#make cross products (the columns I want to operate on are the first 87)
for c1, c2 in combinations(newcolnames, 2):
all_data['{0}*{1}'.format(c1,c2)] = all_data[c1] * all_data[c2]
我可以猜到的问题是我有87个列可以提供3800个新列的顺序(是的,这就是我的意图)。我的jupyter笔记本和ipython shell都在这个计算上窒息。我需要找到一种更好的方法来实现这种乘法。
是否有更有效的矢量化和/或处理方式?也许使用numpy数组(我的数据帧已被处理,现在只包含数字和NAN,它以分类变量开头)。
答案 0 :(得分:1)
正如你在问题中提到NumPy,这可能是一个可行的选择,特别是因为你可能想要在NumPy的2D空间中工作而不是使用pandas进行一维柱状处理。首先,您可以通过调用np.array
将数据帧转换为NumPy数组,如下所示 -
arr = np.array(df) # df is the input dataframe
现在,您可以获得列ID的成对组合,然后将其索引到列中并执行逐列乘法,所有这些都将以矢量化方式完成,如下所示 -
idx = np.array(list(combinations(newcolnames, 2)))
out = arr[:,idx[:,0]]*arr[:,idx[:,1]]
示例运行 -
In [117]: arr = np.random.randint(0,9,(4,8))
...: newcolnames = [1,4,5,7]
...: for c1, c2 in combinations(newcolnames, 2):
...: print arr[:,c1] * arr[:,c2]
...:
[16 2 4 56]
[64 2 6 16]
[56 3 0 24]
[16 4 24 14]
[14 6 0 21]
[56 6 0 6]
In [118]: idx = np.array(list(combinations(newcolnames, 2)))
...: out = arr[:,idx[:,0]]*arr[:,idx[:,1]]
...:
In [119]: out.T
Out[119]:
array([[16, 2, 4, 56],
[64, 2, 6, 16],
[56, 3, 0, 24],
[16, 4, 24, 14],
[14, 6, 0, 21],
[56, 6, 0, 6]])
最后,您可以使用propers列标题(如果需要)创建输出数据框,如下所示 -
>>> headers = ['{0}*{1}'.format(idx[i,0],idx[i,1]) for i in range(len(idx))]
>>> out_df = pd.DataFrame(out,columns = headers)
>>> df
0 1 2 3 4 5 6 7
0 6 1 1 6 1 5 6 3
1 6 1 2 6 4 3 8 8
2 5 1 4 1 0 6 5 3
3 7 2 0 3 7 0 5 7
>>> out_df
1*4 1*5 1*7 4*5 4*7 5*7
0 1 5 3 5 3 15
1 4 3 8 12 32 24
2 0 6 3 0 0 18
3 14 0 14 0 49 0
答案 1 :(得分:0)
您可以尝试df.eval()
方法:
for c1, c2 in combinations(newcolnames, 2):
all_data['{0}*{1}'.format(c1,c2)] = all_data.eval('{} * {}'.format(c1, c2))