【发布时间】:2018-06-26 14:53:26
【问题描述】:
我有以下df:
df = pd.DataFrame({'ID1':[1,2,3,4,5,6],'ID2':[2,6,6,2,1,2],'AREA':[1,1,1,1,1,1]})
...
ID1 ID2 AREA
0 1 2 1
1 2 6 1
2 3 6 1
3 4 2 1
4 5 1 1
5 6 2 1
我这样累积 AREA 列:
for id_ in df.ID1:
id1_filter = df.ID1 == id_
id2_filter = (df.ID1 == id_) | (df.ID2 == id_)
df.loc[id1_filter, 'AREA'] = df.loc[id2_filter].AREA.sum()
print(df)
...
ID1 ID2 AREA
0 1 2 2
1 2 6 5
2 3 6 1
3 4 2 1
4 5 1 1
5 6 2 7
对于ID1 中的每个id_,将AREA 相加,其中ID1 == id_ 或ID2 == id_,
当df 在ID1 上排序时,它总是运行。
我正在处理的真实数据框是 150,000 条记录,每一行都属于一个唯一的 ID1。
在此数据帧上运行上述内容需要 2.5 小时。由于此操作将重复进行
在可预见的未来,我决定将 True 值的索引存储在 id1_filter 和 id2_filter
在具有以下架构的数据库中。
表 ID1:
ID_,INDEX_
1 , 0
2 , 1
etc, ect
表 ID2:
ID_,INDEX_
1 , 0
1 , 4
2 , 0
2 , 1
2 , 3
2 , 5
etc, etc
下次我在AREA 列上运行累积(现在填充了不同的AREA 值)
我阅读了 sql 表并将它们转换为字典。然后我使用这些字典
在求和循环中获取我需要的记录。
id1_dict = pd.read_sql('select * from ID1',db_engine).groupby('ID_').INDEX_.unique().to_dict()
id2_dict = pd.read_sql('select * from ID2',db_engine).groupby('ID_').INDEX_.unique().to_dict()
# print indices for id1_filter and id2_fillter for id 1
print(id1_dict[1])
print(id2_dict[1])
...
[0]
[0, 4]
for id_ in df.ID1:
df.loc[id1_dict[id_], 'AREA'] = df.loc[id2_dict[id_]].AREA.sum()
这样运行只需要6分钟!
我的问题:是否有更好/标准的方法来处理这种情况,即存储数据框选择 以后用?旁注,我在 SQL 表的 ID 列上设置了一个索引,并尝试获取 通过为每个 id 查询 table 来索引,它运行良好,但仍然比上面的时间(9 分钟)长一点。
【问题讨论】:
-
我有一个问题,对于列 AREA 运行一次代码后,第二行有 5 个。这意味着它使用第一行的AREA值已经正确更新并且等于2,而不是1?
-
正确。数据框将始终需要按该顺序运行,也就是说,有时 AREA 将使用先前求和的“AREA”值来计算。这是应该发生的事情,我只需要能够更快地做到这一点。
-
好的,那么另一个问题,ID2 将始终链接到同一个 ID1 还是会改变? (不确定我是否理解您问题的读取 sql 表)
-
所有 ID2 id 都在 ID1 列中,并且给定的 ID2 id 可以与许多不同的 ID1 记录相关联(最多 71 条)。 ID1 列是一系列唯一 ID,也就是我的 df 的 len(df) 为 150000,这意味着 ID1 中有 150000 个唯一 ID。它有点令人困惑,但您可以在我提供的初始示例 df 中看到它。
标签: python postgresql pandas dataframe