Sur la balise pandas, je vois souvent des utilisateurs poser des questions sur la fusion des dataframes chez les pandas. Je vais essayer de faire une question-réponse canonique (auto-réponse) sur ce sujet.
Je tiens à préciser :
Qu’est-ce qui fond ?
Comment utiliser le fondant ?
Quand utiliser le fondant ?
J'ai vu quelques questions courantes sur la fonte, telles que :
Convertir les colonnes en lignes à l'aide de pandas : Celui-ci pourrait en fait être bon, mais plus d'explications seraient bien.
fonction pandas melt : Une bonne question avec une bonne réponse, mais un peu trop vague sans trop d'explications.
Melting pandas dataframe : Également une excellente réponse ! Mais c'est juste pour un cas précis, c'est simple, juste pd.melt(df)
pandas dataframe utilisant des colonnes comme lignes (fondues) : Très soigné ! Mais le problème est qu'il ne répond qu'à la question spécifique posée par le PO, qui nécessite également l'utilisation de pivot_table
.
Je vais donc essayer de faire une séance de questions-réponses canonique sur ce sujet.
Je trouverai toutes les réponses dans cet ensemble de données de notes aléatoires pour des personnes aléatoires à des âges aléatoires (plus facile d'expliquer la réponse :d) :
import pandas as pd df = pd.dataframe({'name': ['bob', 'john', 'foo', 'bar', 'alex', 'tom'], 'math': ['a+', 'b', 'a', 'f', 'd', 'c'], 'english': ['c', 'b', 'b', 'a+', 'f', 'a'], 'age': [13, 16, 16, 15, 15, 13]})
>>> df name math english age 0 bob a+ c 13 1 john b b 16 2 foo a b 16 3 bar f a+ 15 4 alex d f 15 5 tom c a 13
Comment fondre un dataframe pour que le dataframe d'origine devienne le suivant ?
name age subject grade 0 bob 13 english c 1 john 16 english b 2 foo 16 english b 3 bar 15 english a+ 4 alex 17 english f 5 tom 12 english a 6 bob 13 math a+ 7 john 16 math b 8 foo 16 math a 9 bar 15 math f 10 alex 17 math d 11 tom 12 math c
Je veux le transposer de manière à ce qu'une colonne soit pour chaque matière et que les autres colonnes soient les noms répétés des élèves avec leur âge et leurs résultats.
C'est similaire à la question 1, mais cette fois je veux que la question 1 affiche subject
列只有math
,我想过滤掉english
colonne :
name age subject grades 0 bob 13 math a+ 1 john 16 math b 2 foo 16 math a 3 bar 15 math f 4 alex 15 math d 5 tom 13 math c
Je veux que le résultat ressemble à celui ci-dessus.
Si je devais regrouper les fondus et les trier en fonction des scores des élèves, comment ferais-je pour obtenir le résultat souhaité comme celui-ci :
value name subjects 0 a foo, tom math, english 1 a+ bob, bar math, english 2 b john, john, foo math, english, english 3 c tom, bob math, english 4 d alex math 5 f bar, alex math, english
Je dois le trier avec les noms séparés par des virgules et les subjects
séparés par des virgules respectivement dans le même ordre.
Comment puis-je dégeler une trame de données fondue ? Disons que j'ai fait fondre ce dataframe :
df = df.melt(id_vars=['name', 'age'], var_name='subject', value_name='grades')
Devenez :
name age subject grades 0 bob 13 math a+ 1 john 16 math b 2 foo 16 math a 3 bar 15 math f 4 alex 15 math d 5 tom 13 math c 6 bob 13 english c 7 john 16 english b 8 foo 16 english b 9 bar 15 english a+ 10 alex 15 english f 11 tom 13 english a
Alors, comment puis-je le reconvertir dans le bloc de données d'origine, comme indiqué ci-dessous ?
name math english age 0 bob a+ c 13 1 john b b 16 2 foo a b 16 3 bar f a+ 15 4 alex d f 15 5 tom c a 13
Que ferais-je si je voulais regrouper les élèves par nom et séparer les matières et les notes par des virgules ?
name subject grades 0 alex math, english d, f 1 bar math, english f, a+ 2 bob math, english a+, c 3 foo math, english a, b 4 john math, english b, b 5 tom math, english c, a
Je veux un dataframe comme ci-dessus.
Si je devais fondre complètement mon dataframe avec toutes les colonnes comme valeurs, que ferais-je ?
Column Value 0 Name Bob 1 Name John 2 Name Foo 3 Name Bar 4 Name Alex 5 Name Tom 6 Math A+ 7 Math B 8 Math A 9 Math F 10 Math D 11 Math C 12 English C 13 English B 14 English B 15 English A+ 16 English F 17 English A 18 Age 13 19 Age 16 20 Age 16 21 Age 15 22 Age 15 23 Age 13
Je veux un dataframe comme ci-dessus. Toutes les colonnes en tant que valeurs.
Remarque pour la version pandas < 0.20.0 : j'utiliserai df.melt(...)
作为我的示例,但您需要使用 pd.melt(df, .. .)
à la place.
La plupart des solutions ici fonctionneront avec melt
< 一起使用/a>,所以要知道方法melt
, donc pour savoir comment veuillez consulter les
Logique de fusion :
math
和 english
Ensuite, melt fusionne d'abord les colonnes
subject
列,它分别是 grades
Enfin, il ajoute
melt
C'est la logique simple de la fonction
Le problème 1 peut être résolu en utilisant pd.dataframe.melt
print(df.melt(id_vars=['name', 'age'], var_name='subject', value_name='grades'))
id_vars
参数传递给 ['name', 'age']
,然后自动将 value_vars
设置为其他列(['math', 'english']
Ce code convertit ), qui est la transposition, dans ce format.
Vous pouvez également utiliser stack
print( df.set_index(["name", "age"]) .stack() .reset_index(name="grade") .rename(columns={"level_2": "subject"}) .sort_values("subject") .reset_index(drop=true) )
name
和 age
列设置为索引,并堆叠其余列 math
和 english
,并重置索引并指定 grade
作为列名称,然后将其他列重命名为 level_2phpcnendcphp cn 到 <code>subject
然后按subject
Ce code définit les colonnes name
et age
comme index et empile les colonnes restantes et réinitialise l'index et spécifie grade
comme nom de colonne, Renommez ensuite les autres colonnes en level_2phpcnendcphp cn en <code>subject
puis appuyez sur la colonne subject
et enfin réinitialisez à nouveau l'index. Les deux solutions en sortie : 🎜
name age subject grade 0 bob 13 english c 1 john 16 english b 2 foo 16 english b 3 bar 15 english a+ 4 alex 17 english f 5 tom 12 english a 6 bob 13 math a+ 7 john 16 math b 8 foo 16 math a 9 bar 15 math f 10 alex 17 math d 11 tom 12 math c
这和我的第一个问题类似,但是这个我只在 math
列中进行过滤,这时候 value_vars
参数就可以派上用场了,如下所示:
print( df.melt( id_vars=["name", "age"], value_vars="math", var_name="subject", value_name="grades", ) )
或者我们也可以使用 stack
与列规格:
print( df.set_index(["name", "age"])[["math"]] .stack() .reset_index(name="grade") .rename(columns={"level_2": "subject"}) .sort_values("subject") .reset_index(drop=true) )
这两种解决方案都给出:
name age subject grade 0 bob 13 math a+ 1 john 16 math b 2 foo 16 math a 3 bar 15 math f 4 alex 15 math d 5 tom 13 math c
问题3可以通过melt
解决和 groupby
,使用 agg
函数和 ' , '.join
,如下所示:
print( df.melt(id_vars=["name", "age"]) .groupby("value", as_index=false) .agg(", ".join) )
它会融合数据框,然后按等级进行分组,聚合它们并用逗号将它们连接起来。
stack
也可以用来解决这个问题,与 stack
和 groupby
如下所示:
print( df.set_index(["name", "age"]) .stack() .reset_index() .rename(columns={"level_2": "subjects", 0: "grade"}) .groupby("grade", as_index=false) .agg(", ".join) )
这个 stack
函数只是转置数据帧以相当于 melt
的方式,然后重置索引,重命名列、组和聚合。
两种解决方案输出:
grade name subjects 0 a foo, tom math, english 1 a+ bob, bar math, english 2 b john, john, foo math, english, english 3 c bob, tom english, math 4 d alex math 5 f bar, alex math, english
这可以通过 pivot_table
来解决。我们必须指定参数 values
、index
、columns
以及 aggfunc
。
我们可以用下面的代码来解决这个问题:
print( df.pivot_table("grades", ["name", "age"], "subject", aggfunc="first") .reset_index() .rename_axis(columns=none) )
输出:
name age english math 0 alex 15 f d 1 bar 15 a+ f 2 bob 13 c a+ 3 foo 16 b a 4 john 16 b b 5 tom 13 a c
融化的数据帧被转换回与原始数据帧完全相同的格式。
我们首先旋转融化的数据框,然后重置索引并删除列轴名称。
print( df.melt(id_vars=["name", "age"], var_name="subject", value_name="grades") .groupby("name", as_index=false) .agg(", ".join) )
融化并按 name
分组。
或者您可以stack
: p>
print( df.set_index(["name", "age"]) .stack() .reset_index() .groupby("name", as_index=false) .agg(", ".join) .rename({"level_2": "subjects", 0: "grades"}, axis=1) )
两个代码输出:
name subjects grades 0 alex math, english d, f 1 bar math, english f, a+ 2 bob math, english a+, c 3 foo math, english a, b 4 john math, english b, b 5 tom math, english c, a
问题6可以通过melt
解决并且不需要指定列,只需指定预期的列名称:
print(df.melt(var_name='column', value_name='value'))
这会融化整个数据框。
或者您可以stack
: p>
print( df.stack() .reset_index(level=1) .sort_values("level_1") .reset_index(drop=true) .set_axis(["column", "value"], axis=1) )
两个代码输出:
Column Value 0 Age 16 1 Age 15 2 Age 15 3 Age 16 4 Age 13 5 Age 13 6 English A+ 7 English B 8 English B 9 English A 10 English F 11 English C 12 Math C 13 Math A+ 14 Math D 15 Math B 16 Math F 17 Math A 18 Name Alex 19 Name Bar 20 Name Tom 21 Name Foo 22 Name John 23 Name Bob
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!