我有一个由行列表表示的数据网格:
tableData = [
[-27.37, 36.61 , 8.90 , -11.20, -36.03, -42.34],
[16.83 , -33.45, -5.15 , 12.90 , -48.60, -8.70],
[-19.73, 2.64 , 7.21 , 24.16 , 18.38 , 20.47],
[-31.05, 15.07 , 42.69 , -32.13, -36.02, 42.31],
[15.18 , 30.54 , -47.31, 48.38 , 31.60 , -1.98]
]
现在,我想插入两个包含None
值的列,例如列2和3以及4和5之间的列,以便我有以下内容:
tableDataWithNones = [
[-27.37, 36.61 , None, 8.90 , -11.20, None, -36.03, -42.34],
[16.83 , -33.45, None, -5.15 , 12.90 , None, -48.60, -8.70],
[-19.73, 2.64 , None, 7.21 , 24.16 , None, 18.38 , 20.47],
[-31.05, 15.07 , None, 42.69 , -32.13, None, -36.02, 42.31],
[15.18 , 30.54 , None, -47.31, 48.38 , None, 31.60 , -1.98]
]
我可以使用double for循环来完成它:
spacerPositions = [2, 4]
for i in tableData:
for j in reversed(spacerPositions):
i.insert(j, None)
但这并不像是这样做的pythonic方式。
我以为我可以使用numpy来转置数据,这样列可以成为行,然后我可以使用insert
将None
行放入,然后将数据转换回来。但是insert不能为索引取多个值,所以我仍然需要使用for循环。
我有什么想法可以更好地做到这一点吗?
答案 0 :(得分:3)
使用numpy.insert
:
>>> import numpy as np
>>> arr = np.array(tableData)
>>> np.insert(arr, (2, 4), None, axis=1)
array([[-27.37, 36.61, nan, 8.9 , -11.2 , nan, -36.03, -42.34],
[ 16.83, -33.45, nan, -5.15, 12.9 , nan, -48.6 , -8.7 ],
[-19.73, 2.64, nan, 7.21, 24.16, nan, 18.38, 20.47],
[-31.05, 15.07, nan, 42.69, -32.13, nan, -36.02, 42.31],
[ 15.18, 30.54, nan, -47.31, 48.38, nan, 31.6 , -1.98]])
答案 1 :(得分:1)
这种非实用的功能性方法:
from functools import partial
def insertFunc(data, locs):
out = []
for i,d in enumerate(data):
if i in locs:
out.append(None)
out.append(d)
return out
map(partial(insertFunc,locs=spacerPositions),tableData)
将此与
进行比较for i in spacerPositions:
for row in tableData:
row.insert(i, None)
timeit(...,number=10000)
,我得到:
0.144109010696为第一个算法 第二种算法为0.606826066971
这是有道理的,因为insert是O(n)但是append是O(1)。
令人惊讶的是,用numpy计算接受的解决方案:
timeit.timeit('np.insert(arr,(2,4), None, axis=1)',number=10000,setup='import numpy as np;from __main__ import tableData; arr = np.array(tableData)')
给出0.44481992721557617