我有一个这样的数据框
dat = [['ID1', '[1, 0, 1, 0, 0]'], ['ID2', '[0, 0, 1, 0, 0]'], ['ID3', '[1, 0, 1, 1, 0]']]
df = pd.DataFrame(dat, columns = ['ID', 'Values'])
df
ID Values
0 ID1 [1, 0, 1, 0, 0]
1 ID2 [0, 0, 1, 0, 0]
2 ID3 [1, 0, 1, 1, 0]
我想计算每个列表的累计和,并存储在新列中。在此之后,我想取两个列表的点积
df['Values'] = df['Values'].apply(lambda x : ast.literal_eval(x)) # Convert string into list type
df['Cumsum_Values'] = df['Values'].apply(lambda x : np.cumsum(x)) # cumulative sum of each list
df['Dot_Values'] = df.apply(lambda x : np.dot(x.Values, x.Cumsum_Values)) # dot product of columns Values and Cumsum_Values
df
ID Values Cumsum_Values Dot_Values
0 ID1 [1, 0, 1, 0, 0] [1, 1, 2, 2, 2] 3
1 ID2 [0, 0, 1, 0, 0] [0, 0, 1, 1, 1] 1
2 ID3 [1, 0, 1, 1, 0] [1, 1, 2, 3, 3] 6
通过使用pandas
apply
,我可以完成任务。但是,我的记录有数百万,并且其中一些操作花费大量时间(> 10分钟)。
是否有其他选择可以使处理速度更快?
答案 0 :(得分:2)
首先,我认为在good idea中使用list
大熊猫不是这样。
一个想法是,如果每个列表的长度相同,则使用numpy数组,因此,将dot
的每一行改为sum
:
import json
arr = np.array([json.loads(x) for x in df['Values']])
out = np.sum(arr * np.cumsum(arr, axis=1), axis=1)
print (out)
[3 1 6]
df['Dot_Values'] = out
print (df)
ID Values Dot_Values
0 ID1 [1, 0, 1, 0, 0] 3
1 ID2 [0, 0, 1, 0, 0] 1
2 ID3 [1, 0, 1, 1, 0] 6
答案 1 :(得分:2)
也许您可以考虑使用列表理解而不是apply
:
df['Cumsum_Values']=[np.cumsum(ast.literal_eval(i)) for i in df['Values']]
df['dot']=[np.dot(ast.literal_eval(a),b) for a,b in zip(df['Values'],df['Cumsum_Values'])]
ID Values Cumsum_Values dot
0 ID1 [1, 0, 1, 0, 0] [1, 1, 2, 2, 2] 3
1 ID2 [0, 0, 1, 0, 0] [0, 0, 1, 1, 1] 1
2 ID3 [1, 0, 1, 1, 0] [1, 1, 2, 3, 3] 6
比较: