问题描述
我正在学习Pandas数据框以及与性能优化有关的问题。由于我很慢而且很新,所以即使输出正确,我的代码也似乎编写不正确并且性能很差。
问题:我的位模式为0和1。我必须找到步幅1(用于分析的连续数为1)。我的数据框是200,000列x 200行。现在它非常慢,正在寻找一种更好的方法来完成所有列的完整解决方案或使用向量运算进行“ for循环”替换。示例:
Input: 1,1,1
Output: 4,4,2,3,3 (1 is replaced with the stride for 1)
我已经摘录了示例代码以供审核。如果有人可以帮助菜鸟,我将不胜感激。
start_time = timeit.default_timer()
# Small sample
AA = [1,0]
AB = [0,0]
AC = [1,0]
AD = [0,1]
AE = [1,0]
df = pd.DataFrame({"A0": AA,"A1": AB,"A2": AB,"A3": AB,"A4": AB,"A5": AC,"A6": AD,"A7": AE,"A8": AE,"A9": AE})
# End of Debug Data Frame
df2=pd.DataFrame() # initialize to empty
print("Starting")
start_time = timeit.default_timer()
df1=pd.DataFrame(df != df.shift()).cumsum() # Operation-1: detects edges and increments at edge
print("Processing columns. Time=",timeit.default_timer() - start_time)
for c in df1.columns:
df2[c] = df1.groupby(c)[c].transform('count') * df[c] # This takes maximum time as I am counting column by column
print("Done Processing columns. Time=",timeit.default_timer() - start_time)
对于我的数据框(200,000列x 200行),“ for循环”需要700秒
Starting
Processing columns. Time= 0.9377922620624304
Done Processing columns. Time= 701.7339988127351
Done generating data. Time= 702.0729111488909
解决方法
在示例数据帧上,这是一种替代方法,不确定速度差异是否显着,但应该更大。想法是沿行使用cumsum
(一次用于每一列),将{d3}与原始df作为布尔值一起使用,以pd.NA
替换df为1的累积df中的值然后,您需要使用一些bfill
,ffill
和mask
才能获得预期的结果。
df_ = df.cumsum().mask(df.astype(bool)) # Removing pd.NaT helped
df2 = (df_.bfill() - df_.ffill().fillna(0)).fillna(0)
print(df2)
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9
0 1 0 0 0 0 2 0 10 10 10
1 0 8 8 8 8 2 1 10 10 10
2 0 8 8 8 8 0 0 10 10 10
3 2 8 8 8 8 2 1 10 10 10
4 2 8 8 8 8 2 0 10 10 10
5 0 8 8 8 8 0 1 10 10 10
6 0 8 8 8 8 0 0 10 10 10
7 0 8 8 8 8 0 1 10 10 10
8 1 8 8 8 8 1 0 10 10 10
9 0 0 0 0 0 0 1 10 10 10
10 1 1 1 1 1 1 0 0 0 0
11 0 0 0 0 0 0 1 0 0 0
12 5 5 5 5 5 5 0 0 0 0
13 5 5 5 5 5 5 1 0 0 0
14 5 5 5 5 5 5 0 0 0 0
15 5 5 5 5 5 5 1 0 0 0
16 5 5 5 5 5 5 0 0 0 0
17 0 0 0 0 0 0 1 0 0 0
18 0 0 0 0 0 0 0 0 0 0
19 0 0 0 0 0 0 0 0 0 0