【发布时间】:2018-12-17 10:12:55
【问题描述】:
我有一个以下结构的 csv 文件,表示“交互”。
我需要将其转换为标准方阵格式,以便我可以使用为图形编写的其他一些函数(使用 igraph)。
我要转换的 CSV 文件有大约 1.06 亿行,格式如下
node1 node2 interaction strength
XYZ ABC 0.74
XYZ TAH 0.24
XYZ ABA 0.3
ABC TAH 0.42
... (node names are made up to show there is no pattern except node1 is ordered)
我希望这些数据有大约 16K 行和 16K 列的标准格式如下:
XYZ ABC ABA TAH ...
XYZ 0 0.74 0.3 0
ABC 0.74 0 0 0.42
ABA 0.3 0 0 0
TAH 0 0.42 0 0
.
.
.
我不一定需要最后有一个数据框,但我需要以相同的顺序记录行名和列名,并将这个最终矩阵作为 csv 保存到某个地方。
我尝试的是:
import pandas as pd
import progressbar
def list_uniqify(seq, idfun=None):
# order preserving
if idfun is None:
def idfun(x): return x
seen = {}
result = []
for item in seq:
marker = idfun(item)
# in old Python versions:
# if seen.has_key(marker)
# but in new ones:
if marker in seen: continue
seen[marker] = 1
result.append(item)
return result
data = pd.read_csv('./pipelines/cache/fr2/summa_fr2.csv', index_col=0)
names_ordered = helper.list_uniqify( data.iloc[:, 0].tolist() + data.iloc[:, 1].tolist() )
adj = pd.DataFrame(0, index=names_ordered, columns=names_ordered)
bar = progressbar.ProgressBar(maxval=data.shape[0]+1,
widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])
bar.update(0)
bar.start()
print("Preparing output...")
for i in range(data.shape[0]):
bar.update(i)
adj.loc[data.iloc[i, 0], data.iloc[i, 1]] = data.iloc[i, 2]
adj.loc[data.iloc[i, 1], data.iloc[i, 0]] = data.iloc[i, 2]
bar.finish()
print("Saving output...")
adj.to_csv("./data2_fr2.csv")
大约 20-30 分钟后,我只获得了 1%,这意味着这需要大约 2 天,这太长了。
我能做些什么来加快这个过程吗?
注意:我可以并行化这个(8 核,15GB RAM,~130GB SWAP) 但是单核操作需要 15GB RAM,已经有 ~15GB SWAP。我不确定这是否是个好主意。由于没有两个进程会在数据帧的同一个单元格上写入数据,因此我不需要更正竞速条件,对吧?
编辑:以下是建议功能的速度测试,它们比实现的循环要好得多(50K 需要大约 34 秒...)
speeds in seconds for 250K, 500K, 1M rows:
pivot_table: 0.029901999999999873, 0.031084000000000334, 0.0320750000000003
crosstab: 0.023093999999999948, 0.021742999999999846, 0.021409000000000233
【问题讨论】:
标签: python-3.x performance pandas numpy parallel-processing