提高蟒蛇熊猫速度的技术



我有一个大的(3MM记录(文件。

该文件包含四列:[id,startdate,enddate,status]每个id都会有多个状态更改,我的目标是转换这些数据,最终得到一个包含以下列的宽数据帧:

[id, status1, status2, status3... statusN] 

其中,行的值将是id,列的状态的开始日期。

一行的例子是:

["xyz", '2020-08-24 23:42:54', '(blank)', '2020-08-26 21:23:45'...(startdate value for status N)] 

我写了一个脚本,它可以执行以下操作:遍历第一个数据帧的所有行,并将状态存储在一个集合中,这样就不会有重复,我可以获得所有状态的足够列表。

df = pd.read_csv('statusdata.csv')
columns = set()
columns.add('id')
for index, row in df.iterrows():
columns.add(row['status'])

然后,我创建了一个新的数据帧,列为"id",然后从Set 中获取所有其他状态

columnslist = list(columns)
newdf = pd.DataFrame(columns = columnslist)
newdf = newdf[['id']+[c for c in newdf if c not in ['id']]] #this will make 'id' the first column

然后,我遍历原始数据帧的所有列,如果它读取的id不在数据帧中,则在新数据帧中创建一个新记录,然后将原始df中指示的状态的开始日期记录在新df中的匹配列上。

for index, row in df.iterrows():
if row['opportunityid'] not in newdf['id']:
newdf.loc[len(newdf), 'id'] = row['opportunityid']
newdf.loc[newdf['id'] == row['opportunityid'], row['status']] = row['startdate']

我关心的是代码的速度。按照这个速度,将需要13个多小时才能通过原始数据帧的所有行,将其转换为具有唯一密钥的新数据帧。有没有办法提高效率?有没有办法从我的电脑中分配更多的内存?或者有没有办法在aws或其他云计算软件上部署这些代码,使其运行更快?我目前正在一台带有32GB ram的2020款13英寸mac book pro上运行此软件。

谢谢!

IIUC,您可以在不迭代的情况下完成此操作。首先,创建样本数据:

from io import StringIO
import pandas as 
data = '''id, start, end, status
A, 1, 10, X
A, 2, 20, Y
A, 3, 30, Z
A, 9, 99, Z
B, 4, 40, W
B, 5, 50, X
B, 6, 60, Y
'''
df = pd.read_csv(StringIO(data), sep=', ', engine='python')
print(df)
id  start  end status
0  A      1   10      X
1  A      2   20      Y
2  A      3   30      Z
3  A      9   99      Z  # <- same id + status as previous row
4  B      4   40      W
5  B      5   50      X
6  B      6   60      Y

其次,选择感兴趣的列(除了end之外的所有列(;将CCD_ 2和CCD_;squeeze(),以确保对象被转换为熊猫系列;最后将CCD_ 5作为列标签:

t = (df[['id', 'start', 'status']]
.groupby(['id','status'], as_index=False)['start'].max() # <- new
.set_index(['id', 'status'], verify_integrity=True)
.sort_index()
.squeeze()
.unstack(level='status')
)
print(t)
status    W    X    Y    Z
id                        
A       NaN  1.0  2.0  9.0
B       4.0  5.0  6.0  NaN

NaN值显示了当status中没有100%重叠时发生的情况。

更新

我添加了一行数据以导致(id,status(对重复。还添加了groupby()方法来提取最新的(id,status(对。

最新更新