我有一个2-d字典,格式如下:
myDict = {('a','b'):10, ('a','c'):20, ('a','d'):30, ('b','c'):40, ('b','d'):50,('c','d'):60}
Run Code Online (Sandbox Code Playgroud)
如何将其写入制表符分隔文件,以便该文件包含以下内容.填充元组(x,y)将填充两个位置:(x,y)和(y,x).(x,x)始终为0.
输出将是:
a b c d
a 0 10 20 30
b 10 0 40 50
c 20 40 0 60
d 30 50 60 0
Run Code Online (Sandbox Code Playgroud)
PS:如果以某种方式将字典转换为数据帧(使用pandas),那么可以使用pandas函数将其轻松写入文件
你可以用鲜为人知的align方法和一点unstack魔力来做到这一点:
In [122]: s = Series(myDict, index=MultiIndex.from_tuples(myDict))
In [123]: df = s.unstack()
In [124]: lhs, rhs = df.align(df.T)
In [125]: res = lhs.add(rhs, fill_value=0).fillna(0)
In [126]: res
Out[126]:
a b c d
a 0 10 20 30
b 10 0 40 50
c 20 40 0 60
d 30 50 60 0
Run Code Online (Sandbox Code Playgroud)
最后,要将其写入CSV文件,请使用以下to_csv方法:
In [128]: res.to_csv('res.csv', sep='\t')
In [129]: !cat res.csv
a b c d
a 0.0 10.0 20.0 30.0
b 10.0 0.0 40.0 50.0
c 20.0 40.0 0.0 60.0
d 30.0 50.0 60.0 0.0
Run Code Online (Sandbox Code Playgroud)
如果你想把事物保持为整数,DataFrame.astype()那么使用,就像这样:
In [137]: res.astype(int).to_csv('res.csv', sep='\t')
In [138]: !cat res.csv
a b c d
a 0 10 20 30
b 10 0 40 50
c 20 40 0 60
d 30 50 60 0
Run Code Online (Sandbox Code Playgroud)
(由于填充了nan一个帧中的索引从另一个帧中丢失的值的中间步骤,它被转换为浮动)
@Dan Allan使用的答案combine_first很好:
In [130]: df.combine_first(df.T).fillna(0)
Out[130]:
a b c d
a 0 10 20 30
b 10 0 40 50
c 20 40 0 60
d 30 50 60 0
Run Code Online (Sandbox Code Playgroud)
时序:
In [134]: timeit df.combine_first(df.T).fillna(0)
100 loops, best of 3: 2.01 ms per loop
In [135]: timeit lhs, rhs = df.align(df.T); res = lhs.add(rhs, fill_value=0).fillna(0)
1000 loops, best of 3: 1.27 ms per loop
Run Code Online (Sandbox Code Playgroud)
这些时间可能会受到建筑成本的一点污染,那么一些非常庞大的框架会让事情看起来像什么呢?
In [143]: df = DataFrame({i: randn(1e7) for i in range(1, 11)})
In [144]: df2 = DataFrame({i: randn(1e7) for i in range(10)})
In [145]: timeit lhs, rhs = df.align(df2); res = lhs.add(rhs, fill_value=0).fillna(0)
1 loops, best of 3: 4.41 s per loop
In [146]: timeit df.combine_first(df2).fillna(0)
1 loops, best of 3: 2.95 s per loop
Run Code Online (Sandbox Code Playgroud)
DataFrame.combine_first() 更大的帧更快.
In [49]: data = map(list, zip(*myDict.keys())) + [myDict.values()]
In [50]: df = DataFrame(zip(*data)).set_index([0, 1])[2].unstack()
In [52]: df.combine_first(df.T).fillna(0)
Out[52]:
a b c d
a 0 10 20 30
b 10 0 40 50
c 20 40 0 60
d 30 50 60 0
Run Code Online (Sandbox Code Playgroud)
对于后代:如果您只是在调整,请查看Phillip Cloud的答案,以获得更简洁的构建方式df.
| 归档时间: |
|
| 查看次数: |
1586 次 |
| 最近记录: |