Изменение 2-мерного списка в стандартную матричную форму - PullRequest
0 голосов
/ 09 мая 2018
org = [['A', 'a', 1],
       ['A', 'b', 2],
       ['A', 'c', 3],
       ['B', 'a', 4],
       ['B', 'b', 5],
       ['B', 'c', 6],
       ['C', 'a', 7],
       ['C', 'b', 8],
       ['C', 'c', 9]]

Я хочу изменить 'org' на стандартную матричную форму, как показано ниже.

transform = [['\t','A', 'B', 'C'],
             ['a', 1, 4, 7],
             ['b', 2, 5, 8],
             ['c', 3, 6, 9]]

Я сделал небольшую функцию, которая преобразует это. Код, который я написал ниже:

import numpy as np

def matrix(li):
    column = ['\t']
    row = []
    result = []
    rest = []
    for i in li:
        if i[0] not in column:
            column.append(i[0])

        if i[1] not in row:
            row.append(i[1])


    result.append(column)

    for i in li:
        for r in row:
            if r == i[1]:
                rest.append([i[2]])
    rest = np.array(rest).reshape((len(row),len(column)-1)).tolist()

    for i in range(len(rest)):
        rest[i] = [row[i]]+rest[i]

    result += rest

    for i in result:
        print(i)

matrix(org)

Результат был такой:

>>>['\t', 'school', 'kids', 'really']
[72, 0.008962252017017516, 0.04770759762717251, 0.08993156334317577]
[224, 0.004180594204995023, 0.04450803342634945, 0.04195010047081213]
[385, 0.0021807662921382335, 0.023217182598008267, 0.06564858527712682]

Я не думаю, что это эффективно, поскольку я использую так много циклов for. Есть ли эффективный способ сделать это?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Вот еще один «ручной» способ, использующий только numpy:

org_arr = np.array(org)
key1 = np.unique(org_arr[:,0])
key2 = np.unique(org_arr[:,1])
values = org_arr[:,2].reshape((len(key1),len(key2))).transpose()

np.block([
    ["\t",         key1  ],
    [key2[:,None], values]
])

""" # alternatively, for numpy < 1.13.0
np.vstack((
    np.hstack(("\t", key1)),
    np.hstack((key2[:, None], values))
))
"""

Для простоты требуется строго упорядочить входную матрицу (первый столбец старший и возрастающий ...).

Выход:

Out[58]: 
array([['\t', 'A', 'B', 'C'],
       ['a', '1', '4', '7'],
       ['b', '2', '5', '8'],
       ['c', '3', '6', '9']], 
      dtype='<U1')
0 голосов
/ 09 мая 2018

Поскольку вы используете сторонние библиотеки, эта задача хорошо подходит для pandas.

Существует некоторая грязная, но не неэффективная работа по включению индекса и столбцов согласно вашему требованию.

org = [['A', 'a', 1],
       ['A', 'b', 2],
       ['A', 'c', 3],
       ['B', 'a', 4],
       ['B', 'b', 5],
       ['B', 'c', 6],
       ['C', 'a', 7],
       ['C', 'b', 8],
       ['C', 'c', 9]]

df = pd.DataFrame(org)

pvt = df.pivot_table(index=0, columns=1, values=2)

cols = ['\t'] + pvt.columns.tolist()

res = pvt.values.T.tolist()
res.insert(0, pvt.index.tolist())
res = [[i]+j for i, j in zip(cols, res)]

print(res)

[['\t', 'A', 'B', 'C'],
 ['a', 1, 4, 7],
 ['b', 2, 5, 8],
 ['c', 3, 6, 9]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...