在任意位置插入列的Pythonic方式

时间:2013-11-28 17:56:55

标签: python numpy matrix data-manipulation

我有一个由行列表表示的数据网格:

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来转置数据,这样列可以成为行,然后我可以使用insertNone行放入,然后将数据转换回来。但是insert不能为索引取多个值,所以我仍然需要使用for循环。

我有什么想法可以更好地做到这一点吗?

2 个答案:

答案 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