提高python速度的技术

提高python速度的技术,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个大的(3毫米记录)文件 该文件包含四列:[id、startdate、enddate、status]每个id将有多个状态更改,我的目标是转置此数据,并以包含以下列的宽数据框结束: [id, status1, status2, status3... statusN] 其中,行的值为id,列的状态为startdate 行的一个示例是: ["xyz", '2020-08-24 23:42:54', '(blank)', '2020-08-26 21:23:45'...(s

我有一个大的(3毫米记录)文件

该文件包含四列:[id、startdate、enddate、status]每个id将有多个状态更改,我的目标是转置此数据,并以包含以下列的宽数据框结束:

[id, status1, status2, status3... statusN] 
其中,行的值为id,列的状态为startdate

行的一个示例是:

["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”,然后是从集合中获取的所有其他状态

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或其他云计算软件上部署此代码以使其运行更快?我目前正在一台2020 13英寸mac book pro上运行它,内存为32 GB


谢谢

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
NaN值显示在
状态中没有100%重叠时发生的情况

更新


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

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
NaN值显示在
状态中没有100%重叠时发生的情况

更新


我添加了一行数据以导致重复(id、状态)对。还添加了
groupby()
方法以拉出最新的(id、状态)对。

首先,感谢您的及时响应,在运行您非常优雅的脚本后,我得到了一个ValueError,索引包含重复项,无法重塑。因为这是我第一次看到这种类型的df操作,我不知道为什么会这样。您的样品df应涵盖我的df中的所有情况。您有重复的id和重复的状态,我可以添加的一件事是“开始”也可能重复。编辑:我能想到的一件事是,可能存在[id,status]对存在两次的实例(例如,在状态回滚然后重新升级的情况下),我如何处理此问题?您好,我添加了
groupby()。您可以修改groupby()语句以获得最早的开始、最晚的结束等等。先生,您真是个天才。非常感谢。你在哪里学习?我愿意提高我的技能。谢谢!我花了很多时间和熊猫医生在一起,包括——花了我很多时间超过10分钟。另一个来源是(它的焦点是R,但概念是翻译的)。首先,感谢您的及时响应,在运行非常优雅的脚本后,我得到了一个ValueError,索引包含重复的条目,无法重塑。因为这是我第一次看到这种类型的df操作,我不知道为什么会这样。您的样品df应涵盖我的df中的所有情况。您有重复的id和重复的状态,我可以添加的一件事是“开始”也可能重复。编辑:我能想到的一件事是,可能存在[id,status]对存在两次的实例(例如,在状态回滚然后重新升级的情况下),我如何处理此问题?您好,我添加了
groupby()。您可以修改groupby()语句以获得最早的开始、最晚的结束等等。先生,您真是个天才。非常感谢。你在哪里学习?我愿意提高我的技能。谢谢!我花了很多时间和熊猫医生在一起,包括——花了我很多时间超过10分钟。另一个来源是(它的焦点是R,但概念是可以翻译的)。