可以申请熊猫

时间:2019-11-14 06:08:31

标签: python pandas numpy

我有一个这样的数据框

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分钟)。

是否有其他选择可以使处理速度更快?

2 个答案:

答案 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

比较:

enter image description here