Pythonisti, come faccio a spostare i dati da cima a fondo per da sinistra a destra in MySQL (si pensi più valori per ogni ID)?
-
28-09-2019 - |
Domanda
operazione attuale è quello di spostare i dati come mostrato nella tabella 1 a quella della tabella 2.
Tabella (1)
ID Val
-- ---
1 a
1 b
1 c
2 k
3 l
3 m
3 n
colonne Val dipendono dal numero di valori unici per ogni ID. in questo caso si tratta di 3, ma può essere di 20 nel mondo reale!
Tabella (2)
ID Val1 Val2 Val3
-- -- -- --
1 a b c
2 k
3 l m n
Come posso affrontare per valori minori di colonne Val (3 in questo caso):
I creare una tabella temporanea.
create table test(ID int not null, b int auto_increment not null,primary key(ID,b), Val varchar(255));
I quindi inserire i dati in a test.
ottengo il seguente (devo creare le colonne Val manualmente):
ID Val b
-- --- --
1 a 1
1 b 2
1 c 3
2 k 1
3 l 1
3 m 2
3 n 3
So che questo è un processo noioso con molto lavoro manuale. Questo era prima che mi sono innamorato con Python! Una soluzione efficiente in Python per questo problema è molto apprezzato!
Questo è quello che ho finora
import MySQLdb
import itertools
import dbstring
cursor = db.cursor()
cursor.execute("select ID, val from mytable")
mydata = cursor.fetchall()
IDlist = []
vallist = []
finallist = []
for record in mydata:
IDlist.append(record[1])
vallist.append(record[2])
zipped = zip(IDlist,vallist)
zipped.sort(key=lambda x:x[0])
for i, j in itertools.groupby(zipped, key=lambda x:x[0]):
finallist = [k[1] for k in j]
finallist.insert(0, i)
finallist += [None] * (4 - len(finallist)) ### Making it a uniform size list
myvalues.append(finallist)
cursor.executemany("INSERT INTO temptable VALUES (%s, %s, %s, %s)", myvalues)
db.close()
Soluzione
il modo pytonic per farlo è quello di utilizzare itertools.groupby
import itertools
a = [(1, 'a'), (1, 'b'), (2, 'c')]
# groupby need sorted value so sorted in case
a.sort(key=lambda x:x[0])
for i, j in itertools.groupby(a, key=lambda x:x[0]):
print i, [k[1] for k in j]
ritorno
1 ['a', 'b']
2 ['c']