Commencez par préparer la trame de données ci-dessous.
Préparation de DataFrame
import pandas as pd
values = [['1', 'John', 'somekey1-1', 'somevalue1-1', 'time1-1', 'somekey2-1', 'somevalue2-1', 'time2-1'],
['2', 'Tom', 'somekey1-2', 'somevalue1-2', 'time1-2', 'somekey2-2', 'somevalue2-2', 'time2-2'],]
df = pd.DataFrame(values, columns=['id', 'name', 'key1', 'value1', 'time1', 'key2', 'value2', 'time2'])
df
Les données suivantes sont créées avec le code ci-dessus.
id | name | key1 | value1 | time1 | key2 | value2 | time2 | |
---|---|---|---|---|---|---|---|---|
0 | 1 | John | somekey1-1 | somevalue1-1 | time1-1 | somekey2-1 | somevalue2-1 | time2-1 |
1 | 2 | Tom | somekey1-2 | somevalue1-2 | time1-2 | somekey2-2 | somevalue2-2 | time2-2 |
J'introduirai quatre codes qui convertissent ces informations en données verticales comme indiqué ci-dessous.
id | name | key | value | time | |
---|---|---|---|---|---|
0 | 1 | John | somekey1-1 | somevalue1-1 | time1-1 |
1 | 2 | Tom | somekey1-2 | somevalue1-2 | time1-2 |
2 | 1 | John | somekey2-1 | somevalue2-1 | time2-1 |
3 | 2 | Tom | somekey2-2 | somevalue2-2 | time2-2 |
Il semble qu'il soit courant d'utiliser la méthode de fusion, et cette information était abondante. Il existe plusieurs façons de créer un tableau de colonnes, je vais donc l'inclure également.
Créer un tableau de noms de colonnes
#Motif ①
columns = df.columns.tolist()
[value for value in columns if value.startswith('key')]
#Motif ②
df.columns[df.columns.str.startswith('key')].tolist()
#résultat
# ['key1', 'key2']
Le motif ①, qui crée et déplace une fois un tableau de colonnes, semble se déplacer plus léger, donc J'utilise ça ci-dessous.
Convertir en données verticales à l'aide de la fusion
columns = df.columns.tolist()
pd.concat(
[pd.melt(df, id_vars=['id', 'name'], value_vars=[value for value in columns if value.startswith('key')], value_name='key'),
pd.melt(df, value_vars=[value for value in columns if value.startswith('value')], value_name='value'),
pd.melt(df, value_vars=[value for value in columns if value.startswith('time')], value_name='time')
],
axis=1
).drop('variable', axis=1)
wide_to_long est assez simple car vous pouvez le créer en une seule ligne. Je n'ai pas compris au début quand j'ai regardé le site ci-dessous, https://pandas.pydata.org/docs/reference/api/pandas.wide_to_long.html
Dans le tableau spécifié par le deuxième argument, `convertir une colonne commençant par un caractère spécifique en maintien vertical Parce qu'il bouge, il est possible de le compléter en une seule ligne.
La partie restante de la colonne est spécifiée par «j»
S'il s'agit de «key1», créez-le avec le nom de colonne spécifié, et s'il s'agit de «key2», créez-le avec «2».
Dans le code ci-dessous, une colonne appelée'drop'est créée, donc après cela, elle est supprimée par la méthode drop
.
wide_to_Convertir en données verticales en utilisant long
pd.wide_to_long(df, ['key','value','time'], i='id', j='drop').reset_index().drop('drop', axis=1)
Que faire si vous obtenez l'erreur suivante L'erreur suivante est une erreur qui se produit lorsqu'il existe des éléments d'ID en double.
error
ValueError: the id variables need to uniquely identify each row
Par exemple, si vous modifiez un peu le premier bloc de données et que vous l'exécutez avec les deux identifiants définis sur «1», vous obtiendrez une erreur.
DataFrame avec une erreur
import pandas as pd
values = [['1', 'John', 'somekey1-1', 'somevalue1-1', 'time1-1', 'somekey2-1', 'somevalue2-1', 'time2-1'],
['1', 'Tom', 'somekey1-2', 'somevalue1-2', 'time1-2', 'somekey2-2', 'somevalue2-2', 'time2-2'],]
df = pd.DataFrame(values, columns=['id', 'name', 'key1', 'value1', 'time1', 'key2', 'value2', 'time2'])
pd.wide_to_long(df,['key','value','time'], i='id', j='drop').reset_index().drop('drop', axis=1)
Dans ce cas, vous pouvez le résoudre en créant un élément d'index avec reset_index ()
et en le spécifiant dans id.
wide_to_Convertir en données verticales en utilisant long(Méthode d'évitement des erreurs)
pd.wide_to_long(df.reset_index(), ['key','value','time'], i='index', j='drop').reset_index().drop('drop', axis=1).drop('index', axis=1)
lreshape
semble être une méthode mineure qui peut être corrigée pour remodeler
même si vous recherchez sur google.
Personnellement, je l'aime parce que c'est simple, mais le site ci-dessous dit qu'il disparaîtra dans le futur, il semble donc qu'il ne sera pas utilisable bientôt. Pardon.
https://pandas.pydata.org/pandas-docs/version/1.0.0/whatsnew/v1.0.0.html
Convertir en données verticales à l'aide de lreshape
d = {'key': df.columns[df.columns.str.startswith('key')].tolist(),
'value': df.columns[df.columns.str.startswith('value')].tolist(),
'time': df.columns[df.columns.str.startswith('time')].tolist(),}
pd.lreshape(df, d)
De plus, bien qu'il faille écrire qu'il est utilisé dans la pratique, pour une raison quelconque, ce qui suit Il semble préférable de ne pas trop l'utiliser car cela peut provoquer des erreurs.
error
/usr/local/lib/python3.6/dist-packages/pandas/core/reshape/melt.py in <dictcomp>(.0)
188 mask &= notna(mdata[c])
189 if not mask.all():
--> 190 mdata = {k: v[mask] for k, v in mdata.items()}
191
192 return data._constructor(mdata, columns=id_cols + pivot_cols)
IndexError: boolean index did not match indexed array along dimension 0; dimension is 1210 but corresponding boolean dimension is 24200
Probablement pas très bien. Quand je ne connaissais pas la méthode ci-dessus au début, je l'ai fait.
Lors de l'utilisation de la méthode concat si les noms de colonne sont identiques C'est une méthode pour l'utiliser car il se joint verticalement.
Implémentation avec concat
pd.concat([
df[['id', 'name', 'key1', 'value1', 'time1']].rename(columns={'key1': 'key', 'value1': 'value', 'time1': 'time'}),
df[['id', 'name', 'key2', 'value2', 'time2']].rename(columns={'key2': 'key', 'value2': 'value', 'time2': 'time'}),
])
Recommended Posts